121

Is it possible to specify the width and height of a tikzpicture? To scale a tikzpicture I use the option scale, i.e. for instance

\begin{tikzpicture}[scale = 2]
...
\end{tikzpicture}

I tried to change the width and height as

\begin{tikzpicture}[width = 2in, height = 3in]
...
\end{tikzpicture}

but this gives me an error "I do not know the key /tikz/width".

  • 12
    With a tikzpicture, you specify all the coordinates, so the picture is as big as needed. With pgfplots, the size of the plot is computed, so you can specify the width and height options to the axis environment within a tikzpicture. – Peter Grill Oct 05 '12 at 17:52
  • @PeterGrill Yes. I am not using pgfplots though. I should have not tagged the question with pgfplots. I have removed the tag now. –  Oct 05 '12 at 18:29
  • 5
    Ok, but I was trying to explain why it does not make sense to specify the height/width of a tikzpicture, but does make sense to be able to specify the height/width of a pgfplots graph. With a tikzpicture only the scale option makes sense. – Peter Grill Oct 05 '12 at 18:31
  • @PeterGrill Ok. Yes I understood. –  Oct 05 '12 at 18:46
  • Related: http://tex.stackexchange.com/questions/6388/how-to-scale-a-tikzpicture-to-textwidth – Torbjørn T. Oct 05 '12 at 20:43

10 Answers10

73

EDIT:

I came back here to add information about the tikzscale package, however I found an answer about that already in this thread. I believe you will want to give it a try.


Use resizebox outside of tikzpicture.

\resizebox{width}{height}{object}

For example:

\documentclass{article}
\usepackage{tikz}

\begin{document}
    \begin{figure}
        \centering
        \resizebox{\columnwidth}{!}{%
            \begin{tikzpicture}
                \node [draw] (my node 1) {my node 1};
                \node [draw, anchor = west] (my node 2) at (my node 1.east) {centro};
                \node [draw, anchor = west] at (my node 2.east) {my node 3};
            \end{tikzpicture}%
        }
    \end{figure}
\end{document}
egreg
  • 1,121,712
tcpaiva
  • 2,574
  • 25
    But in this solution also things like line widths and font sizes get resized, right? In this case graphics would no longer stay consistent when they have to be resized by different amounts. – Benedikt Bauer Oct 05 '12 at 18:04
  • 2
    I agree with you, but doing so is the purpose of the question, no? – tcpaiva Oct 05 '12 at 18:37
  • 6
    Not sure about that. I could imagine that the intention is that you can draw your graphic in any relative coordinates or units of measure such that it is automagically sized to a certain width or height. Of course this should happen in a way that the line widths and fonts keep their sizes. Theoretically you could achieve that by drawing everything in units of a variable \picturewidth or so, but this would be rather unconvenient. – Benedikt Bauer Oct 05 '12 at 18:51
  • 1
    Oh I forgot before: I think the idea is that you don't have to care that much about how large your graphic will get at the end. Instead you can just start drawing and will in most cases end up with a graphic that has the desired width or height. – Benedikt Bauer Oct 05 '12 at 19:12
  • 2
    The problem with this solution is that labels get resized too. For example if I only change the height or width then the labels look stretched. – Spenhouet Dec 21 '17 at 10:09
  • @Spenhouet If you set only the width or the height, and set the other to !, then the image will be resized without changing the aspect ratio. – FWDekker Feb 29 '24 at 13:03
32

Converting my comments to an answer as I think question is more about specifying a height, width option rather than how to scale picture to get it to be of the appropriate size.

Summary:

It does not make sense to specify the height/width of a tikzpicture, but does make sense to be able to specify the height/width of a pgfplots graph. With a tikzpicture only the scale option makes sense.

Explanation:

Within a tikzpicture, you specify all the coordinates, so the picture is as big as needed. So, if you say draw a line from (0,0) to (4,0) you get a line that is 4cm long (cm being the default unit of measurement). So applying a scale factor of say 0.5 would make this line 2cm long. But what does it mean to say draw a line of 4cm in a box that is 2cm wide?
Perhaps you want to only view the parts of the picture in the first 2.0cm, then you are clipping the picture, and there is a macro to do that called \clip.

Now, by default the units are assumed to be cm, so (4,0) corresponds to 4cm in the x-direction. There is an option to specify to use different units with the x=<length>, but again this is scaling.

However, with graphing packages such as pgfplots, the size of the plot is computed, and one can make a determination as to what physical size corresponds to a unit in each of the axis directions. So, for the case of plotting graphs it makes perfect sense to have options to specify the height, or width of the graph.

So, in my mind it does not make sense to have options to specify the height or width of a tikzpicture but does make sense to be able to apply a scale option. For graphing environments such as pgfplots it makes prefect sense to be able to specify a height, and width, and these are available in the axis environment options.

Peter Grill
  • 223,288
  • 6
    I don't understand. Why wouldn't it make sense to draw the picture, then scale it by whatever factor gives width = \textwidth? – Chris Chudzicki Nov 04 '13 at 01:22
  • @mrc: Perhaps my answer was not clear: It does make sense to scale a tikzpicture. – Peter Grill Nov 04 '13 at 02:12
  • 7
    I'm sure I misunderstood your answer. I know you said scaling makes sense, but why not scaling by specifying what the width should be after the picture is scaled? – Chris Chudzicki Nov 04 '13 at 02:31
  • @mrc: Sorry for the delayed response. When you specify to tikz that a picture should consist of a horizontal line that is 1cm long, and a scale=0.5, and that the width of the picture be 3cm, which one is supposed to determine how wide the picture is? Perhaps what you are asking about is How to scale a tikzpicture to \textwidth. – Peter Grill Jan 12 '15 at 20:58
  • 2
    I certainly wouldn't expect to be able to specify scale=0.5 and width=3cm simultaneously. The question you linked to is interesting. Still, I would have expected that tikz would accept keys like width=0.8\textwidth . . . the behavior I would expect is that tikz would draw the unscaled picture, then scale it proportionally so that the width has the desired value. I didn't look too carefully---that seems to be what is described in the question you linked to---I am just confused about why that isn't the default behavior of tikz. – Chris Chudzicki Jan 13 '15 at 23:02
  • I have a case where I use \mathrlap and what is inside that command is not impacting the size of the picture. So there are case where specifying the dimensions (not a scaling) could help as it would allow to have the picture big enough to display what is inside the \mathrlap{} command. – Togh Oct 25 '16 at 15:30
  • @Togh: Without a MWE it is hard to respond to your comment. The content within the\mathrlap is not really something that should be scaled and I would use\widthof` to adjust any sizing of the equations to ensure that the contents width was noticed where it was needed. – Peter Grill Oct 26 '16 at 04:16
  • @Peter Grill It was more to comment on the fact that one may want to have some control over the dimensions of a tikzpicture without changing the scaling (so basically adding some white space around). But I don't pretend it's a good idea to come to that kind of wish. – Togh Nov 04 '16 at 21:36
22

I know this is a rather old post, but it did show up in google as a first result, so I want to add one solution here that is still missing.

If you have your tikzpicture in a individual file, like in Tom Bombadil's answer, you can use the package tikzscale. Then in your document you can use

\includegraphics[width=\linewidth]{mytikzpic}

The file mytikzpic.tikz only includes the tikzcode:

%mytikzpic.tikz
\begin{tikzpicture}

%some tikz code

\end{tikzpicture}

tikzscale uses an iterative approach to scale the picture to the desired size, thereby compiling the picture code several times. This will lengthen the compile time of the document. It works well with tikz externalize library though, with which one can save most of that overhead again.

Dux
  • 1,260
15

Simply consider using the PGFplots keys /pgfplots/width and /pgfplots/width as follows.

\begin{tikzpicture}
  \begin{axis}[
    width=.8\textwidth,
    height=.8\textheight,
    ]
  ...
  \end{axis}
\end{tikzpicture}

More details in the pgfplots manual (search for the aforementioned keys, circa page 295).

10

This uses part of my answer to this question: first, the image is drawn virtually to get the scaling factors, then it is drawn using these factors.

Code

\documentclass{scrartcl}
\usepackage[margin=20mm]{geometry}
\usepackage{tikz}
\usepackage{filecontents}
\usepackage{xifthen}

\newcommand{\getsizes}[2]% width, height
{   \path (current bounding box.south west);
    \pgfgetlastxy{\xsw}{\ysw}
    \path (current bounding box.north east);
    \pgfgetlastxy{\xne}{\yne}
    \pgfmathsetmacro{\picwidth}{(\xne-\xsw)/28.453}
    \pgfmathsetmacro{\picheight}{(\yne-\ysw)/28.453}
    \pgfmathsetmacro{\picxscale}{#1/\picwidth}
    \pgfmathsetmacro{\picyscale}{#2/\picheight}
    \xdef\xsca{\picxscale}
    \xdef\ysca{\picyscale}
}

\newcommand{\xyscaledtikz}[3]% draw commands, width, height
{ \smash{\vphantom{
    \begin{tikzpicture}
        #1
        \getsizes{#2}{#3}
    \end{tikzpicture}
    }}
    \begin{tikzpicture}[xscale=\xsca,yscale=\ysca]
        #1
    \end{tikzpicture}
}

\begin{filecontents}{sample.tex}
\draw[rotate=30,left color=red,right color=blue] (0,0) rectangle (5,5);
\end{filecontents}

\begin{document}

\xyscaledtikz{\input{picone}}{2}{3}
\xyscaledtikz{\input{picone}}{6}{1}

\xyscaledtikz{\input{picone}}{2}{7}
\xyscaledtikz{\input{picone}}{4}{4}

\end{document}

Output

enter image description here

Tom Bombadil
  • 40,123
  • This is the correct answer. Very good. If you just want to scale to a given height but leave the aspect ratio, replace xscale=\xsca by xscale=\ysca. The same applies for defining width and compute height automatically. – kap Sep 15 '14 at 12:13
6

Try something like \draw[use as bounding box] (0,0) rectangle (3,2) or(\path) if you don't want to draw) to change the aspect ratio of your image, then use scale to change the size. But I agree with Benedikt and Peter that scaling the dimensions separately will warp the picture you are trying to draw, and that you should probably not be looking for such an option in the first place.

  • Nice. Most of the time I resort to this hack. I define a command like \newcommand*{\setbbox}{\path[use as bounding box] (-2,-1.8) rectangle (4.2,4);} whose dimensions must be tweaked on a case by case basis (sigh). Then inside each tikzpicture I start with \setbbox. It's not very pretty, but it's quick to set up. – PatrickT Apr 22 '23 at 22:56
3

In some cases it might make sense to specifically define the width and height. For example, I want to create an image for a presentation that adds new elements on each slide. So I want the different images to be the same size in order not to move around the slide. My workaround is to define a white spot somewhere in the right, lower corner that is not visible in the images but keeps the size constant for all images. The position of the spot will then define the width and height of the image.

Christine
  • 175
2

I don't know how useful this will be to others, but I found adding a node that defines a minimum width and height worked pretty well for me. I needed this because one of my nodes was of a variable width, but I needed the image to be anchored to the bottom right of the page.

The code would look like:

\draw (0, 0) node[inner sep=0,anchor=east,minimum width=8.75in, minimum height=112pt] {};

Make sure to change the anchor as needed.

The downside here is that if any of your nodes go outside the area defined by the first node, you picture will still grow to be larger. You might be able to avoid that by using the \clip option inside a scope, but I didn't experiment with that.

0

There is the package adjustbox. You can place the tikzpicture into it to resize it. It also scales text, so it is very similar to what you would get from includegraphics.

clel
  • 325
0

I use the following workaround to set a fixed width and height of a tikzpicture.

  • I set the tikzfigure scale fixed to 1
  • I draw an invisible line in the diagonal of the picture \path[draw=none] (0,0) -- (width,height);
  • I then draw the rest of the picture in that canvas.

If you had already drawn the picture before setting the invisible canvas line, you can shift the invisible path, or rescale the rest of the nodes within the tikzpicture to make it fit the canvas.