This is rather general inquiry, with intent to find out how to go about this the best way with the less time-consuming the better. How would you draw a graphics with lots of rectangles (or other similar forms) with TikZ?

  • Would you make each bit a node?

  • Would you use some advanced node positioning methods, or maybe use a matrix?

Little explanation for the example below: it's a sketch of a lab machine. There are obviously lots of rectangular shapes and nearly equally many nodes "pointing" to them. On the right of the nodes (and currently not visible) are the same rectangular shapes, just rotated by 90°, in the sense of a sectional drawing.


MWE 01 (picture below), first attempt





text width=3.5cm,
minimum height=1cm, %use this because text width makes the text bottom-aligned

%the following foreach loop would obviously increase the speed of drawing the shapes on the left, but it is, as far as I can see, entirely without any coherent content -> a foreach loop is unfortunately of no use, also because of different lengths and heights
%\foreach \y in {0,2,4,6,8}{
%\node[draw, rectangle, text width=5cm, text height=1cm, align=center] at (0,\y) {aaa};}
\node[draw, rectangle, text width=4cm, text height=1.5cm, align=center] (node01) at (0,2) {node1};
\node[draw, rectangle, text width=4cm, text height=2cm, align=center] (node02) at (0,4) {node2};
\node[draw, rectangle, text width=5cm, text height=1.5cm, align=center] (node03) at (0,6) {node3};
\node[draw, rectangle, text width=3cm, text height=1.5cm, align=center] (node04) at (0,8) {node4};
\node[draw, rectangle, text width=4cm, text height=1.5cm, align=center] (node05) at (0,10) {node5};
%the 'descriptive' nodes on the right can be placed in this matter and the loop enables a somewhat uniform 'descriptive' look
%but with using a loop, I am clueless as to how I can name each node then
\foreach \x/\y in {{Stuff and lots of other words}/0,Word/2,Text/4,aaa/6,bbb/8}{
    \node[descr] at (0,\y) {\x};}

Picture for MWE 01

enter image description here

  • This is a question, which tend to be closed because it is too broad... – user31729 Jul 13 '14 at 9:14
  • 1
    TikZ has a pin similar to label. You can add draw option to it. – percusse Jul 13 '14 at 9:14
  • 1
    It's much simpler if you make a MWE so people can offer different solutions. Otherwise this is bound to have misunderstandings and updates – percusse Jul 13 '14 at 10:31
  • 1
    There is no general answer, I don't think, beyond 'it depends'. It depends on the diagram and on what you (or we) know how to do! For example, I'm working on a timeline at the moment and right now, I've placed some nodes using \foreach loops and some manually. I am using some commands to automate some of the placement and to reduce typing but I'm not using entirely the same strategy even for different parts of the same diagram... – cfr Jul 13 '14 at 23:41
  • 1
    In addition to absolute coordinates, you can use relative coordinates and things like [above] and (node01.north). Add the calc library and you can do things like ($(node01.east)!.333!(node01.west)$). – John Kormylo Jul 14 '14 at 22:32

I don't know if I could claim "best practices," but here is an alternative for part of the drawing shown at the top. Note: the actual width and height of a node is the text width and height plus the inner sep. Also, I threw out a lot of unused code simply because I am anal retentive. The choice between lots of \draws or \nodes or lumping them together is purely esthetic.


  (0,2) node[draw, text width=5cm, text height=2cm, inner sep=0pt] (node01) {}% mostly for the anshors
  (node01.south) node[above] {node1};% an easier way to align text to bottom, or top etc.
  ($(node01.west)!0.25!(node01.east)$) circle[radius=5mm]
  (node01.center) circle[radius=5mm]
  ($(node01.west)!0.75!(node01.east)$) circle[radius=5mm];
  (node01.north) node[draw, above, text width=4cm, text height=1cm, inner sep=0pt] (node02) {}
  (node02.north) node[draw, above,  text width=1cm, text height=3cm, inner sep=0pt] (node03) {}
  (node03.north) node[draw, below, text width=2cm, text height=1cm, inner sep=0pt] (node04) {}
  (node04.center) node[draw, text width=7mm, text height=7mm, inner sep=0pt] (node05) {};
% Note: without the calc below the line would stop at (node03.north)
\draw[very thin, dash dot] (node01.south)+(0,-5mm) -- ($(node03.north)+(0,5mm)$);


As for loops, I have always felt that unless you NEED a loop, don't use one. Partly this goes back to my Cray programming days, where a loop with less than 8 cycles is worse than repeating the code.

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.