0

Hi All: I have a code snippet below which works beautifully and was provided by someone on this list to me a while back. But now I want to change it so that I draw one long rectangle instead of the adjacent five boxes. The text inside the rectangle should just be at the far right of it and could say $Y^{*}_{whatever}$. I'm thinking that I need to define a rectnode instead of a squared node with different things in it. But I don't understand how to make it the same length as the length of the boxes and in the same position. "minimum size" currently inside the definition of squarednode isn't making sense to me.

EDIT:

I have edited this question by including a handwritten drawing in order to express the fact that I need the rectangles to line up with the horizontal axis as shown. So, the first rectangle travels from 0 to 5. The second rectangle travels from 1 to 6, etc all the way to the 6th rectangle travelling from 5 to 10.

Also, all the rectangles should be the same width and length even though it may not seem that way by the picture. I also don't need a y-axis.

Thanks and I'm sorry for not being clearer the first time.

Desired output

\begin{tikzpicture}[
squarednode/.style={draw=black, minimum size=9.9mm},
y=1.5cm
]
  
%boxes

    \draw (0.5, 5.5) node[squarednode] {$X_{1}^{*}$};
    \draw (1.5, 5.5) node[squarednode] {$X_{2}^{*}$};
    \draw (2.5, 5.5) node[squarednode] {$X_{3}^{*}$};
    \draw (3.5, 5.5) node[squarednode] {$X_{4}^{*}$};
    \draw (4.5, 5.5) node[squarednode] {$X_{5}^{*}$};
            
    \draw (1.5, 4.5) node[squarednode] {$X_{2}^{*}$};
    \draw (2.5, 4.5) node[squarednode] {$X_{3}^{*}$};
    \draw (3.5, 4.5) node[squarednode] {$X_{4}^{*}$};
    \draw (4.5, 4.5) node[squarednode] {$X_{5}^{*}$};
    \draw (5.5, 4.5) node[squarednode,dashed] {0};

    \draw (2.5, 3.5) node[squarednode] {$X_{3}^{*}$};
    \draw (3.5, 3.5) node[squarednode] {$X_{4}^{*}$};
    \draw (4.5, 3.5) node[squarednode] {$X_{5}^{*}$};
    \draw (5.5, 3.5) node[squarednode,dashed] {0};
    \draw (6.5, 3.5) node[squarednode,dashed] {0};
    
    \draw (3.5, 2.5) node[squarednode] {$X_{4}^{*}$};
    \draw (4.5, 2.5) node[squarednode] {$X_{5}^{*}$};
    \draw (5.5, 2.5) node[squarednode,dashed] {0};
    \draw (6.5, 2.5) node[squarednode,dashed] {0};
    \draw (7.5, 2.5) node[squarednode,dashed] {0};
    
    \draw (4.5, 1.5) node[squarednode] {$X_{5}^{*}$};
    \draw (5.5, 1.5) node[squarednode,dashed] {0};
    \draw (6.5, 1.5) node[squarednode,dashed] {0};
    \draw (7.5, 1.5) node[squarednode,dashed] {0};
    \draw (8.5, 1.5) node[squarednode,dashed] {0};
    
    \draw (5.5, 0.5) node[squarednode,dashed] {0};
    \draw (6.5, 0.5) node[squarednode,dashed] {0};
    \draw (7.5, 0.5) node[squarednode,dashed] {0};
    \draw (8.5, 0.5) node[squarednode,dashed] {0};
    \draw (9.5, 0.5) node[squarednode,dashed] {0};
                    
\end{tikzpicture}
6
  • 3
    would you like to add a handdrawn sketch of the desired output
    – js bibra
    Jul 1 '20 at 5:44
  • M. Al Jumally. Is there a way to include the pdf of the output ? I have the pdf but I don't know how to include it. thanks.
    – mark leeds
    Jul 1 '20 at 6:07
  • M. Al. Jumally: I managed to write code like this and it works !!! \draw (0.0,5.5) rectangle (5.0,6.0); but then, I try to put text at the end in order to put it inside the rectangle and that gives me an error. \draw (0.0,5.5) rectangle (5.0,6.0) {$Y^{*}_{11:00-11:05}$};
    – mark leeds
    Jul 1 '20 at 6:51
  • So, my question is: Is there a way to make a rectangle and then specify that one wants some text at the far end of the rectangle ? thanks so much.
    – mark leeds
    Jul 1 '20 at 6:55
  • You can take a screenshot of the pdf and paste it into the question. I am sure it will be much easier for you to explain and for others to answer :) Jul 1 '20 at 16:25
0

With the help of the options of Ignasi's answer, here is a complete and short solution to your request (note, the red dashed lines are just there if you needed them). There are two types of shapes: rectangleNode and dashedSquared. rectangleNode will have the text at far right whereas dashedSquared will be an empty square. The idea is simple, we draw the rectangle first and assign it a name (say, n1), then draw the square (without assigning it a name) and use right=0pt of n1 to position it correctly. The 0pt is how far pt units away from the rectangle. I attached two outputs: the vertical line between them is solid and dashed. For the dashed version, we just need to also add fill=white, right=-\pgflinewidth of n1. The fill is needed to overdraw the vertical line of the rectangle. The \pgflinewidth is the width of the line (which is really tiny but exact :)).

Output

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{ifthen}

\begin{document}
    \begin{tikzpicture}[
        rectangleNode/.style={
            draw=black, align=right, 
            minimum width=10em, minimum height=2.5em, 
            outer sep=0pt, inner sep=0pt, 
            text width=9em,%change size to adjust the text position
        },
        dashedSquared/.style={
        draw=black,dashed, minimum height=2.5em, minimum width=2em
        },
        every node/.style={outer sep=0pt, inner sep=0pt}
    ]
    \node[rectangleNode] (n1) at (0,0) {$X_{1}^{*}$};%reference point
    %\node[dashedSquared, right=0pt of n1]{};%reference point
    % uncomment the previous line and comment out the next if you want solid
    % vertical line between the rectangle and square.
    \node[dashedSquared, fill=white, right=-\pgflinewidth of n1]{};

    % Comment the following three lines if you will use the dash pattern.
        \foreach \x in {2,...,6}{% 6 is the number of boxes in total
            \pgfmathtruncatemacro{\prevNode}{\x - 1}
             \node[
             rectangleNode, 
             right = 2em of n\prevNode, % horizontal dist between
                                                          % rectangles is 2em units
             yshift=-0.5em,             % vertical dist between 
                                                 %rectangles is 0.5em units (negative)
             below of = n\prevNode,
             ] (n\x){$Y_{\x}^{*}$};
             \ifthenelse{\x=6}{
                % last rectangle, don't add the dashed box (do nothing).
             }{
                % not the last rectangle, append the square.
                 \node[dashedSquared, right=0pt of n\x]{};%reference point
                % comment out the previous line and uncomment next if you want dashed
                % vertical line between the rectangle and square.
                %\node[dashedSquared, fill=white, right=-\pgflinewidth of n\x]{};
             }
        }
        % Adding labels and ticks. Create label0 as 
        % starting point and then use a for loop.
        \node[red, below=19em of n1.south west](label0){$0$};
        \draw[]([yshift=0.8em]label0.south) -- ([yshift=0.8em]label0.north);%ticks
        \foreach \x in {1,...,10}{
            \pgfmathtruncatemacro{\prevNode}{\x - 1}
            \node[red, right=1.5em of label\prevNode](label\x){$\x$};
            \draw[]([yshift=0.8em]label\x.south) -- ([yshift=0.8em]label\x.north);%ticks
             %\draw (\i-3,-7)--++(90:3mm) node[below]{\i};
        }
        % Adding red dashed lines.
         \foreach \x in {1,...,6}{
            \pgfmathtruncatemacro{\label}{\x - 1}
            \draw[red, dashed] (n\x.south west) -- ([yshift=1em]label\label.north);
        }
        % X axis line
        \draw[blue]([yshift=0.5em, xshift=-0.5em]label0.north west) --
         ([yshift=0.5em]label0.north west -| label10.north east);
        % Y axis line
        \draw[blue, thick] ([xshift=-0.5em]n1.north west) -- 
        ([xshift=-0.5em]n1.north west|-label0.north);
        % X axis label
        \node[above right =0.6em and 1em of label10.center]{min};
    \end{tikzpicture}
\end{document}

Simple breakdown of the code:

  • \prevNode is just an integer which will temporarily be (and in order) 1, 2, 3, 4, 5.
  • -0.5em is the vertical distance between the nodes (the comment stated 1em but should have stated -0.5em instead (sorry!) and now corrected). It needs to be negative since we are placing the first node at the top, hence, the second node and onward needs to be placed below.
  • (n\x) is appending n and the value of x (which is an integer), together. For example, if \x is 3, then (n\x) evaluates to (n3). The same goes to n\prevNode, it appends n with the value of \prevNode (\prevNode is also an integer).
  • Furthermore, you might be able to see that n\prevNode is nₓ₋₁ (x-1ᵗʰ node) and n\x is nₓ (xᵗʰ node).
  • Lastly, the node (n1) is hardcoded since we need to have a starting point. So, the for loop starts at 2, and refers to the previous node n\prevNode = n1 and create the new node (n\x) = (n2). Then, the loop continues to 3 and previous node is n2 where current node is n3 and so on.
21
  • It looks great. I will print out and try to comprehend. Thanks so much.
    – mark leeds
    Jul 3 '20 at 20:16
  • Jumally: I've gone through some tutorials so my knowledge is a little better but not much. I sort of get it but I definitely couldn't do it myself. But, if you can answer the following questions, it's much appreciated. 1) Is prevnode a macro that always refers to the previous node ? 2) if yshift = -0.5em then why is the distance 1em ? What does the n mean in n\prevNode and in (n\x). Thanks.
    – mark leeds
    Jul 7 '20 at 22:17
  • AI Jumally. Apologies for writing your name incorrectly in the previous comment.
    – mark leeds
    Jul 7 '20 at 22:42
  • M Al Jumally: That was a great explanation. My only question is by putting (n\x) {$Y_{\x}^{*}$}, I think you're creating a new node. Is there a location where the new node is being created ? Thanks. I learned a lot from your code and explanation. But I needed both :).
    – mark leeds
    Jul 7 '20 at 23:09
  • Al Jumally: I know that I'm getting greedy but since I actually understand your code now, would you mind making a horizontal axis that has the same alignment as my picture. Ignasio made one but I'm not sure what will happen if I take his and put it in your code. Somehow, I don't think that's going to work but I'll try it and see what happens !!!! Thanks.
    – mark leeds
    Jul 7 '20 at 23:18
2

By default, node's contents are centered inside the node, but if you define some text width, then you can use align option to align the text to left or right.

An example:

\documentclass[border=1mm,tikz]{standalone}

\begin{document}
\begin{tikzpicture}
\node [draw, minimum width=5cm, minimum height=1cm, text width=4cm , align=right] {Hello};
\end{tikzpicture}
\end{document}

enter image description here

In case you don't know desired dimensions, you can use fit library to define the new node. In this case, the text can be included with the label option.

\documentclass[border=1mm,tikz]{standalone}

\usetikzlibrary{matrix, positioning, fit}
\usepackage{mathtools}

\begin{document}

\begin{tikzpicture}[
squarednode/.style={draw=black, minimum size=9.9mm},
]
  
\matrix (A1) [matrix of math nodes, column sep=-\pgflinewidth,
    nodes={squarednode, anchor=center}]
    {X_{1}^{*} & X_2^* & X_3^* & X_4^* & X_5^*\\};

%Use inner nodes coordinates because matrix node is larger.
\node[fit=(A1-1-1.north west) (A1-1-5.south east), inner sep=0pt, label={[left]0:$Y^{*}_{\text{whatever}}$}, draw, below=3mm of A1] {};
                    
\end{tikzpicture}
\end{document}

enter image description here

EDIT: solution to real question

\documentclass[tikz,border=2mm]{standalone}

\begin{document}
\begin{tikzpicture}[y=1.5cm]
\foreach \i in {0,1,...,5}
    \node[minimum width=5cm, minimum height=1cm, 
        anchor=north west, text width=4.5cm, align=right, draw] at
        (\i,-\i) {$Y_\i$};
\draw (0,-6) -- ++(0:10.5) node[right] {min};
\foreach \i in {0,...,10}
    \draw ([yshift=2mm]\i,-6)--++(-90:4mm) node[below]{\i};
\end{tikzpicture}
\end{document}

enter image description here

7
  • all I can say is wow and thanks. this is all new to me so much appreciated. I'll go over it carefully. oh, as far as trying ( emphasis on trying !!! LOL ) to learn this material, I imagine you recommend the over 1000 page documentation. that seems to be what everyone points to. thanks again.
    – mark leeds
    Jul 1 '20 at 16:09
  • just a heads up that although your solutions were great, I didn't explain my problem clearly enough. So, I edited my question and included a drawing. I'm sorry for not being clear the first time. I'm also trying to understand your solutions (and possibly modify for my problem ) but it's not easy. I was trying to learn the tikz basics so adding fit on top of that is another level of complexity. Thanks for anything you can do.
    – mark leeds
    Jul 2 '20 at 5:36
  • @markleeds I've edited the answer with a solution for your new question. Hope it helps. About the manual, of course it's worth to read it and of course it's intimidating. But you can start with initial tutorials. They are easy to read and are a complete introduction to Tikz. After that you will know a lot about tikz and just need to read particular topics in the rest of the book.
    – Ignasi
    Jul 3 '20 at 7:37
  • yes. I think going through smaller tutorials, is better for me. I have found some and am going through them. Still, there's no easy way to learn this material and some people are just plain better than others ( from birth I guess ). Thank you for the edit. I will keeps yours checked but try to understand both. That's easier said than done of course.
    – mark leeds
    Jul 3 '20 at 20:19
  • Hi: I've gone through some tikz tutorials but I still don't feel terribly knowledgeable. When you have a chance, if you could answer the following questions at your convenience, it would be really appreciated. 1) In the first foreach loop why does the negative eye work ? I would think some of the y coordinates would be positive ? 2) The next to last statement draws the axis but what does the ++(0:10.5) node[right] {min} do ? The last foreach loop makes the horizontal coordinates but the only part of the statement that I understand is the \i ,-6. Thank you very much for your help.
    – mark leeds
    Jul 7 '20 at 22:41

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.