125

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?

jub0bs
  • 58,916
Dror
  • 22,613
  • 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 07 '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. – Andrew Stacey Mar 07 '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 08 '11 at 06: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 08 '11 at 07: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 07:04

5 Answers5

86
\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);

Hendrik Vogt
  • 37,935
Alain Matthes
  • 95,075
78

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}%
Habi
  • 7,694
  • 50
    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
  • 3
    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 06:50
  • 2
    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
  • 2
    @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
  • How do we avoid overwriting existing LaTeX macros? I'm afraid I'm going to blow up my entire book if this happens. – Atcold Feb 16 '22 at 21:36
74

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

\documentclass{article}
\usepackage{tikz}
\begin{document}

\usetikzlibrary{math} %needed tikz library

% Variables must be declared in a tikzmath environment but % can be used outside (almost anywhere) % Do not forget SEMICOLONS after each command (!) \tikzmath{\x1 = 1; \y1 =1; % Computations are also possible \x2 = \x1 + 1; \y2 =\y1 +3; }

% Using the variables for drawing \begin{tikzpicture} \draw[very thick, -stealth] (\x1, \y1)--(\x2, \y2); \end{tikzpicture}

% Using the variables in math and text modi The coordinates of the second point are:

$x_2 = \x2$ and $y_2 =$ \y2

% Note that the name of the variables, e.g., \x1, % can contain a number as the LAST name characters (!) % That would be not allowed with a \newcommand definition \end{document}

The result of the code above

See also this answer for more examples with different uses.

  • 7
    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
  • I get an output from tikzmath in the pdf output. – Antonio Sesto Mar 22 '23 at 09:16
  • @AntonioSesto Sorry, but I do not know exactly what you mean :. The code above works flawlessly when the needed packages are installed. You will have to pose a new question in TeX-StackExchange ;) – loved.by.Jesus Mar 22 '23 at 15:06
  • One missing remark: when using numbers in the name, they have to be the last characters, otherwise, an error will be returned. – Diaa Dec 01 '23 at 21:49
  • 1
    @Diaa Your remark has improved the answer. Thanks! – loved.by.Jesus Dec 04 '23 at 18:10
  • @ChrisSewell You're not really cluttering the general namespace since \def won't affect anything outside the local group. And I don't think this library was even available when most of the answers were written (but I'm not certain about that). – cfr Dec 04 '23 at 19:04
45

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}
bobobobo
  • 4,396
  • 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 08 '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 08 '12 at 17:26
  • 3
    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 09 '12 at 07:17
7

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

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751