85

I guess this is a very simple question, but I couldn't find the answer... How can I define a variable in TikZ? I want to have something like, for example:

\draw[->] (x1,y1)--(x2,y2);

Such that x1,x2,y1,y2 are defined somewhere else and can be changed in order to adjust the picture.

Should be simple, right?

  • Since you chose the pgfplots tag, do you have anything particular in mind that concerns drawing things in pgfplots. There are some special things inside its axis environments, like the axis cs and rel axis cs coordinate systems that might be helpful for you, so maybe you could edit your question to give more details (or remove the pgfplots tag if you actually meant TikZ in general). – Jake Mar 7 '11 at 18:15
  • The "right" answer to this depends on how you envision specifying x1, x2, y1, and y2. If you just want to vary them explicitly, then the \newcommand approach is as good as any. If they are coordinates, then the \coordinate approach is best. But if they are to be computed from something else, then something a little more complicated (but not much) is needed; however, exactly what depends on how you want to specify them. – Loop Space Mar 7 '11 at 20:19
  • @Andrew: Can you elaborate regarding the last option you mentioned? I want to use TikZ for drawing/plotting mathematical objects. For example, provide a point and a slope and plot the corresponding line (or at least a segment of it). Then, I want to compute and plot intersection of two such lines and so on and so forth.. – Dror Mar 8 '11 at 6:56
  • 1
    Maybe Alain Matthes' package tkz-euclide that he refers to in an answer to another question could be helpful for you? There are quite a few examples on his website. – Jake Mar 8 '11 at 7:20
  • @Jake: I'm looking for something more straightforward, where I can "program" my plot as directly as possible, relaying on TikZ. Moreover, I failed to install tkz-euclid on my mac... – Dror Mar 10 '11 at 7:04
59
\begin{tikzpicture} 
\coordinate (A) at (2,3);
\coordinate (B) at (2,5);
\draw[->] (A)--(B) ;
\end{tikzpicture}

You can add

\newcommand\XA{2} etc. and then \coordinate (A) at (\XA,\YA);

58

I'm using \def\x{1068} to have x as a variable in my script to generate scalebars onto images with TikZ. That works like a charm for me.

A working example is pasted below, even though the image does not look very nice :)

\documentclass{article}
\usepackage[demo]{graphicx}
\usepackage{tikz}
\usepackage{siunitx}
\usepackage[graphics,tightpage,active]{preview}
\PreviewEnvironment{tikzpicture}
\newcommand{\imsize}{\linewidth}
\newlength\imagewidth % needed for scalebars
\newlength\imagescale % ditto
\begin{document}%
%-------------
\pgfmathsetlength{\imagewidth}{\imsize}%
\pgfmathsetlength{\imagescale}{\imagewidth/1728}%
\def\x{1068}% scalebar-x at golden ratio of x=1728px
\def\y{320}% scalebar-y at 90% of height of y=356px
\def\shadow{11}% shadow parameter for scalebar
\begin{tikzpicture}[x=\imagescale,y=-\imagescale]
\clip (0,0) rectangle (1728,356);
    \node[anchor=north west, inner sep=0pt, outer sep=0pt] at (0,0) {\includegraphics[width=\imagewidth]{image}};
    % 279px = 1.7819mm > 100px = 638um > 78px = 500um, 16px = 100um
    \draw[|-|,blue,thick] (791,151) -- (1020,311) node [sloped,midway,above,fill=white,semitransparent,text opacity=1] {\SI{1.7819}{\milli\meter} (1204px) TEMPORARY!};
\draw[|-|,thick] (\x+\shadow,\y+\shadow) -- (\x+78+\shadow,\y+\shadow) node [midway, above] {\SI{500}{\micro\meter}};
    \draw[|-|,white,thick] (\x,\y) -- (\x+78,\y) node [midway,above] {\SI{500}{\micro\meter}};
    \draw[color=red, anchor=south west] (0,356) node [fill=white, semitransparent] {Legend} node {Legend};
\end{tikzpicture}%
%-------------
\end{document}%
  • 31
    Yes, so to be clear your answer is \def\varname{initialValue}. I think your example is far too complicated to show use of a simple variable. – bobobobo Oct 25 '12 at 17:49
  • 2
    You're of course right that the answer could be written much shorter, but I wanted to show a full example on how I use \dev\varname{initialValue}. – Habi Oct 26 '12 at 6:50
  • 1
    Then, how we can use the defined variable somewhere else where we need to divide it by, for example, 2? \varname/2? \varname*0.5? – Rasoul Feb 10 '13 at 19:00
  • 1
    @Rasoul Yes, exactly. I'm using it like \x+78+\shadow in the fifth line from bottom. Dividing works too. Try changing said line to \draw[|-|,white,thick] (\x/2,\y) -- (\x/2+78,\y) node [midway,above] {\SI{500}{\micro\meter}}; and you see that the white scalebar moves... – Habi Feb 11 '13 at 15:24
34

I use \pgfmathsetmacro{VARName}{VARValue} inside a tikzpicture environment.

For example:

\begin{tikzpicture}

%VARIABLES
\pgfmathsetmacro{\PHI}{-15}

% Now use \PHI anywhere you want -15 to appear,
% can also be used in calculations like 2*\PHI

\end{tikzpicture}
  • The number is not special \begin{tikzpicture} \def\PHI{-15} \node (o) at (0,0) {o}; \node (a) at (\PHI mm,\PHI mm) {a}; \end{tikzpicture} also works. However this command is useful to store the result of a mathematical operation such as \pgfmathsetmacro{\PHI}{cos(60)} – percusse Aug 8 '12 at 15:20
  • Yes, I'm aware you can embed an entire macro in \pgfmathsetmacro but there is no harm in using it for constants. – bobobobo Aug 8 '12 at 17:26
  • 2
    Two remarks : first it's more complicated, the definition of \pgfmathsetmacro: \begingroup% \pgfmathsetlength\pgfmath@x{#2}% \edef#1{\pgfmath@tonumber{\pgfmath@x}}% \pgfmath@smuggleone{#1}% \endgroup% . The second remark you can use \pgfmathsetmacro outside a tikzpicture environment. – Alain Matthes Aug 9 '12 at 7:17
31

Tikz offers a powerful solution to dealing with variables through the library math (TikZ version >= 3.00)

   \usetikzlibrary{math} %needed tikz library

   \begin{document}
     \begin{tikzpicture}
       %Variables must be declared in a tikzmath environment but
       % can be used outside
       \tikzmath{\x1 = 1; \y1 =1; 
                   %computations are also possible
                    \x2 = \x1 + 1; \y2 =\y1 +3; } 
       \draw[->] (\x1, \y1)--(\x2, \y2);
     \end{tikzpicture}
    \end{document}

The result of the code above

  • 3
    Thanks! I think this is a lot better approach than cluttering the general namespace with \def or \newcommand variables – Chris Sewell Aug 10 '18 at 23:41
6

Building on the example in the comments to the question, here's a more complicated example that uses some computations to find the desired coordinates and then uses them.

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}
\draw[gray,thin] (-1,-1) grid (5,5);
\draw[ultra thick,->] (-1,0)  -- (5.2,0);
\draw[ultra thick,->] (0,-1) -- (0,5.2);
\clip (-1,-1) rectangle (5,5);
\foreach \m/\c/\col in {
  3/{(2,0)}/blue,
  2/{(1,1)}/red,
  -.25/{(0,4)}/green%
} {
  % Separate the coordinate \c into x and y components
  \fill[\col] \c circle (2pt);
  \pgfgetlastxy{\vx}{\vy}
  % Work out the y-height at one end of the line
  \pgfmathsetmacro{\ey}{\vy + \m*(5 cm -\vx)}
  % Work out the y-height at the other end of the line
  \pgfmathsetmacro{\by}{\vy - \m*(\vx+1 cm)}
  \draw[thick,\col] (-1,\by pt) -- (5,\ey pt);
}
\end{tikzpicture}
\end{document}

lines from slope and point

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.