2

How to draw a graph like below and where should I start from?

enter image description here

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
3

I particularly like Zarko's answer but I am lazy and like to let LaTeX do the work for me so I would do this by defining a linegraph pic so that I could draw the line graph using the command:

\pic{linegraph={1,2,1,3,1,0.5,1.5}};

that, as above, results in the graph:

enter image description here

In particular, the minimum and maximum values are marked automatically. Here is the code, which used ferahfeza's answer as the starting point:

\documentclass{article}
\usepackage{tikz}
\usepackage{amsmath}

\tikzset{
  pics/linegraph/.style = {
    code = {
       \def\mymax{-1000}
       \def\mymin{1000}
       \foreach \y in {#1} { % determine min and max values
         \pgfmathparse{max(\y,\mymax)}\xdef\mymax{\pgfmathresult}
         \pgfmathparse{min(\y,\mymin)}\xdef\mymin{\pgfmathresult}
       }
       \foreach \y [count=\c] in {#1} {
           % use \pgfmathparse to determine the appropriate label
           \pgfmathparse{\y==\mymax}
           \ifnum\pgfmathresult=1\def\mylabel{\text{max}}
           \else
             \pgfmathparse{\y==\mymin}
             \ifnum\pgfmathresult=1\def\mylabel{\text{min}}
             \else\def\mylabel{\c}
             \fi
           \fi
           % draw the line
           \draw [->,densely dashed](\c,0)--++(90:\y) node[above]{$x_{\mylabel}$};
       }
    }
  }
}

\begin{document}

    \begin{tikzpicture}
      % Draw the axes
      \draw [<->] (0,4)node[right]{$y$}|-(8,0)node[right]{$x$};

      % draw the line graph
      \pic{linegraph={1,2,1,3,1,0.5,1.5}};
    \end{tikzpicture}

\end{document}

There is a very small amount of pain in determining whether a given point is at the maximum or minimum value and the code will automatically mark multiple maximums and minimums. Note that I have used the amsmath package \text command so that max and min are printed as text and not mathematics.

If the x-coordinates are not given by the consecutive integers then it is easy to modify the code above so that it would accepts input of the form:

\pic{linegraph={0.9/1,2/2,3.1/1,3/53,4/1,5.2/0.5,6.3/1.5}};

That is, a comma separated list of x and y values.

Of course, if you are only drawing one of these graphs then perhaps it is not worth all of the effort! If you are drawing two or more of these then I would wrap all of the code inside a macro so that you could just type \LineGraph{1,2,1,3,1,0.5,1.5} :)

EDIT

Here is a macro version that also draws appropriately sized axes:

\documentclass{article}
\usepackage{tikz}
\usepackage{amsmath}

\tikzset{
  pics/linegraph/.style = {
    code = {
       \def\mymax{-1000}
       \def\mymin{1000}
       \foreach \y in {#1} {
         \pgfmathparse{max(\y,\mymax)}\xdef\mymax{\pgfmathresult}
         \pgfmathparse{min(\y,\mymin)}\xdef\mymin{\pgfmathresult}
       }
       \foreach \y [count=\c] in {#1} {
           \pgfmathparse{\y==\mymax}
           \ifnum\pgfmathresult=1\def\mylabel{\text{max}}
           \else
             \pgfmathparse{\y==\mymin}
             \ifnum\pgfmathresult=1\def\mylabel{\text{min}}
             \else\def\mylabel{\c}
             \fi
           \fi
           \draw [->,densely dashed,blue](\c,0)--++(90:\y) node[above]{$x_{\mylabel}$};
           \xdef\lastC{\c}
       }
      % finally the axes
      \draw [<->] (0,\mymax+1)node[above]{$y$}|-(\lastC+1,0)node[right]{$x$};
    }
  }
}

\newcommand\LineGraph[1]{\tikz\pic at (0,0) {linegraph={#1}};}

\begin{document}

   \LineGraph{1,2,1,3,1,0.5,1.5}

\end{document}

The output is much the same as before except that I have adjusted for the questions in the comments.

  • would you able to make the plot in blue color, like the Zarko's answer? – aan Jan 17 at 14:38
  • @aan Sure just replace \draw [->,densely dashed]... with \draw [->,densely dashed,blue]... – Andrew Jan 17 at 15:42
  • thanks a lot. Your code is very well written. Between, how to put the $y$ label on top of the arrow, rather than right hand side of the arrow? I had tried draw [<->] (0,4)node[top]{$y$}, but not working – aan Jan 17 at 18:01
  • @aan Try node[above]{$y$}. Btw, if you like an answer and it was helpful, please consider upvoting (by clicking on the arrows next to the score) and marking it as accepted answer (by clicking on the checkmark ✓). – Andrew Jan 17 at 18:15
  • thanks a lot. Yours code is quite good. – aan Jan 18 at 11:45
9

Using \pic definition.

pics/lines/.style args={#1-#2-#3}{

Our pic command has three parameters.

First parameter (#1) : x coordinate.

Second parameter (#2) : Magnitude of vector.

Third parameter (#3) : If this parameter is equal to 1001 or more one, the label of vector is x_max else is equal to 0, the label is x_min. For normal labeling, give any number, for example 1.

Code:

\documentclass[margin=3mm]{standalone}

\usepackage{tikz}

\tikzset{%
pics/lines/.style args={#1-#2-#3}{
    code={
   \ifnum #3>1000 
   \draw [->,densely dashed](#1,0)--++(90:#2)node[above]{$x_{max}$};
   \else 
   \ifnum #3=0
    \draw [->,densely dashed](#1,0)--++(90:#2)node[above]{$x_{min}$};
   \else 
       \draw [->,densely dashed](#1,0)--++(90:#2)node[above]{$x_{#1}$};
       \fi
       \fi
    }
  }
}

\begin{document}

\begin{tikzpicture}[>=latex]
\draw [<->] (0,4)node[right]{$y$}|-(8,0)node[right]{$x$};
\pic {lines={1-1-1}};
\pic {lines={2-2-1}};
\pic {lines={3-1-1}};
\pic {lines={4-3-1001}}; % <-- Max Value > 1000
\pic {lines={5-1-1}};
\pic {lines={6-0.5-0}};% <-- Min Value = 0
\pic {lines={7-1.5-1}};
\end{tikzpicture}
\end{document}

enter image description here

  • @ferehfeza, thanks. Can I know what is the meaning of \begin{tikzpicture}[>=latex]? I seemed cannot add in caption for this figure. – aan Jan 17 at 0:37
  • @aan, you welcome. It is for arrow styling. You can change it, for example [>=stealth] or whatever you want. You can check the TikZ manual. – ferahfeza Jan 17 at 12:58
  • @ferahfeze, thanks. i have another question, why unable to add caption in your code? tex.stackexchange.com/questions/524629/… – aan Jan 17 at 13:33
  • @aan, because you are in standalone class. Change your class, for example, to article. Or add preview option to standalone class. – ferahfeza Jan 17 at 20:19
4

With the pgfplots package:

\documentclass[margin=3mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.16}
\usetikzlibrary{arrows.meta}

\begin{document}
    \begin{tikzpicture}
\begin{axis}[
    axis lines = middle,
    axis line style={-Stealth},
    xlabel=$x$, ylabel=$y$,
    x label style={anchor=west},
    y label style={anchor=south},
    xmin=0, xmax=6.5,
    ymin=0, ymax=5.5,
    ticks=none,
            ]
\addplot +[nodes near coords, ycomb, 
           densely dashed, mark=triangle*,
           every mark/.append style={solid},
           point meta=explicit symbolic]
           table [meta=label] {x y label
                               1 2 $x_1$
                               2 3 $x_2$
                               3 1 $x_{\min}$
                               4 4 $x_4$
                               5 5 $x_{\max}$
                               6 3 $x_6$
                               };
\end{axis}
    \end{tikzpicture}
\end{document}

@a

  • Thanks. Would we able to put the x lable beside the arrow and not below the arrow? – aan Jan 17 at 13:40
  • 1
    @aan, of course. I put it there since there is on your provided image. See edited answer. – Zarko Jan 17 at 13:45
  • thanks a lot. I want to ask one more question. is there a way to make the x-axis spread wider? Now is quite narrow and do not look like a graph. I had tried ` \pgfplotsset{width=10cm,compat=1.16}, the compat=1.16` is fixed right? – aan Jan 17 at 13:56
  • @ann, if you like, you can say width=\linewidth˙ (in \pgfplotsset) and image width will be equal to text width. You can also move this option to options of axis`. – Zarko Jan 17 at 14:04
  • Thanks. width=\linewidth seemed too large. Anyway, why I cannot change the number in compat=1.16. Is it fixed at 1.16? – aan Jan 17 at 14:11
4

It should be easy to modify the following to something you want:

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

    \begin{tikzpicture}
    % Draw the axes
    \draw [<->,thick] (0,2) node (yaxis) [above] {$y$}
    |- (3,0) node (xaxis) [right] {$x$};

    %Draw a coordinate
    \coordinate[label=$x_1$] (c) at (1,1);

    %Draw an arrow to the coordinate
    \draw[<-, dashed] (c) |- (xaxis);
    \end{tikzpicture}

\end{document}

The code renders this:

the graph

I guess the \draw[<-, dashed] (c) |- (xaxis); was the hard part about this. And I'm also not sure if this is the proper way to do this. In my opinion this looks a little messy. It would be nice if we could get some clarification about this by someone else.

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.