1

This post is my help to beginners in LaTeX that are trying to plot functions and came out after trying to help with this post How to Draw 2 Functions In Tex, but my answer is more general and has to deal with basic tikz and pgf function plotting but also (and most) is a suggestion and a "how to" for plotting functions in case we really know the formula and in case we don't. The approach of the answer is to show to the newcomer that if he/she doesn't really know the actual formula, and even if he/she know a form, the math needed sometimes make the question out of this site's purposes and are closer to https://math.stackexchange.com/ but here.

Question: How can I plot a function like this:

enter image description here

6
  • After precalculus in high school students should be familiar with polynomials, exponentials, logarithms, absolute value, floor functions, square root and cube root. In studying exponential functions, it's not uncommon see the logistics equation (which is the solution given in the link you post to). By being familiar with parent functions and transformations the student should be able to say: "That looks like the sine function!" they should be able to fit a formula that resembles the curve.
    – DJP
    Commented Apr 12, 2018 at 16:55
  • Forgot to mention the obvious trig functions as well.
    – DJP
    Commented Apr 12, 2018 at 17:03
  • @DJP... Almost every country uses another (may be simmilar but may be much different) approach... A function can be really complex and be a combination of functions that the student can not even imagine that will involve in the formula... The specific function happens to seem like a part of a -sin(\alpha x)+1 as marmot already mentioned... but could be a moved arctan() too... But could be anyghing... I just started to write an answer for the linked post... but without knowing the function... and with knowing after the edit there... But the function could be anything
    – koleygr
    Commented Apr 12, 2018 at 17:05
  • The think I tried (but failed) to make clear... Is that both a moved arctan or a moved part of sin functions could be ok for our plot... But could not be ok too... So, we have sometimes ways to look for and to find the real formula (that is at most a mater of math.se than tex.se) but also we could just use a combination of curves approach that could be ok for our purpose. (These depends on the kind of our work etc)...
    – koleygr
    Commented Apr 12, 2018 at 17:10
  • Your comment is confusing. Both sin and arctan could be used to construct a graph resembling your curve. But you say it "...could be ok for our plot... But could not be ok too.". Why wouldn't it be okay?
    – DJP
    Commented Apr 12, 2018 at 17:17

4 Answers 4

3

Here is the code of a full answer that can be read as a pdf or directly:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\section{Ploting Mathematical Functions Using tikz or pgfplots}

Let's suppose we want to plot a function like this:

\begin{center}
\begin{tikzpicture}
  \draw[-,blue!30!green] (0,0)to[out=0,in=225](1.5,1);
  \draw[-,blue!30!green] (1.5,1)to[out=45,in=190](3,2);
\end{tikzpicture}
\end{center}

\subsection{The easy way (without real function):}

\subsubsection{Observe the function:}
We have just to pay attention to the properties of the function that has to be ploted. Here we need:

\begin{itemize}
\item The function has to start from about $(0,0)$ with almost zero (but possitive) derivative.
\item The function has to pass through $(1.5,1)$ with a derivative of about 1 (angle of $45^{\circ}$)
\item The function has to finish on point $(3,2)$ by a derivative of about 0 and possitive.
\end{itemize}

\subsubsection{tikz tools}

The tool we will use is the lines and arrows of tikz:

\begin{itemize}
\item An axis can be drawn with (here it is a x axis):
  \verb|\draw[->,thick] (0,0)--(3.5,0);|


\begin{itemize}
  \item In the above example (0,0) is the starting point and (3.5,0) is the finishing
  point.
\item \verb|->| means ``draw arrow'' for tikz.
\item \verb|--| connects these two points with an arrow (because of the previous)  
\end{itemize}

\item A grid can be ploted like this (here it is vertical lines between 0 and 3 by 0.5 units (of x) and between -0.2 and 2.5 (of y)):

\begin{verbatim}
\def\ymax{2.5}
\foreach \x in {0,0.5,...,3.5}{
\draw[-,thin] (\x,-0.2)--(\x,\ymax);}
\end{verbatim}

\begin{itemize}
\item In the above code\verb| \foreach| is a command that will be executed for each one of the values 0, 0.5, 1, 1.5 \ldots that are named (and can be used) as \verb|\x|
\item The line discribed before, but now it is a thin line.
\item In the finished example we will use two \verb|\foreach| commands to draw both $x$ and $y$ grids.
\end{itemize}


\item A curved line (here the function) can be drawn like this:

  \verb|\draw[-] (0,0) to[out=10,in=235](1.5,1);|
  \begin{itemize}
  \item (0,0) and (1.5,1) are the starting and ending points.
  \item \verb|out| is the angle which the line is going to follow to get out of the first point (See below).
    \item \verb|in| is the angle which the line is going to follow to get in the second point.
  \end{itemize}

  We can remember the angles by creating imaginatively an analog clock where
  3 o'clock is 0 degrees and 12 o'clock is 90 degrees etc:

  \begin{tikzpicture}
    \draw (2,-5) circle (3);
    \node at  (2,-5) {\LARGE clock};
    \node (A)at (5,-5) {$0^\circ$};
    \node (B)at (-1,-5) {$180^\circ$};
    \node (C)at (2,-2) {$90^\circ$};
    \node (D)at (2,-8) {$270^\circ$};
    \node[rotate=45] (E)at (4.1,-2.9) {$45^\circ$};
    \node at ([xshift=-1.cm]A) {3 o'clock=};
    \node at ([xshift=1.2cm]B) {=9 o'clock};
    \end{tikzpicture}


    A line that starts with $45^{\circ}$ by the point (0,0) and ends to a point (2,0) by $160^{\circ}$ can be drawn whith the command
    \verb|\draw (0,0)to[out=45,in=160](2,0);|:

    \begin{tikzpicture}
        \draw (0,0) circle (5pt);
        \draw (2,0) circle (5pt);
        \draw (0,0)to[out=45,in=160](2,0);
    \end{tikzpicture}

  \item A \verb|\node| is something that we will use here to add labels in the axes

    The node command can be used with coordinates and conetent, but the most usefull thing we have to know here is that can optionally have an `anchor' to be left,or east, or below etc of the point like:

    \verb|\node[left] at (3,2) {Content};|

    \end{itemize}

    \subsubsection{Plotting the function}

\begin{center}
  \begin{tikzpicture}[scale=2.5]
    \draw[->,thick] (-0.2,0)--(3.7,0);%x axis
    \draw[->,thick] (0,-0.2)--(0,2.7);%y axis
    \foreach \y in {0,0.5,...,2.5}{
      \draw[-,thin] (0.,\y)--(3.5,\y);
      \node[left] at (0,\y) {\y};
    }
    \foreach \x in {0,0.5,...,3.5}{
      \draw[-,thin] (\x,0)--(\x,2.5);
      \node[below] at (\x,0) {\x};
    }
  \draw[-,blue!30!green] (0,0)to[out=5,in=225](1.5,1);
  \draw[-,blue!30!green] (1.5,1)to[out=45,in=185](3,2);
\end{tikzpicture}
\end{center}


\subsection{The math way (using -extracting- the fanction):}

We want the graph to pass through $(0,0)$\footnote{Condition 1} and $(3,2)$\footnote{Condition 2} in a way that in $(1.5,1)$\footnote{Condition 3}
has a zero second derivative\footnote{Condition 4} and at $(3,2)$\footnote{Not a real condition} the first direvative will be almost zero.
(4 conditions)

The known shape comes from a function like:
$$f(x)=\frac{\alpha}{\beta+1\cdot e^{-\gamma (x+t)}}$$
(4 parameters)\footnote{The value of 1 as a mulriplier to $exp$ function
is just one of our free selected constand, since if we use any value, $\alpha$ and $\beta$ can always be written in a way that gives the same final function}

\begin{itemize}
\item Condition 1:\\
$$f(0)\approx 0 \Longrightarrow \alpha<< \beta+e^{-\gamma(t)} \Longrightarrow$$

\begin{equation}\alpha-\beta<< e^{-\gamma t}\label{eq:1}\end{equation}

\item Condition 4:\\
$$f^{\prime\prime}(1.5)=0 \Longrightarrow$$
But every derivative will give a product of $\alpha$, $exp(-\gamma(x+t))$ and $(x+t)$... And only $x-t$ can get zero, Thus, by knowing that $x=1.5$:
\begin{equation}
  t=-1.5
\end{equation}
\item Condition 2:\\
  $$f(3)=2\Longrightarrow$$
  \begin{equation}\label{eq:3}
    \alpha=2\beta+2\cdot e^{-1.5\gamma}
  \end{equation}
\item Condition 3:\\
  Finally condition 3 gives:
    $$f(1.5)=1\Longrightarrow$$
  \begin{equation}
    \alpha=\beta+1
  \end{equation}
  which combined with \eqref{eq:1} [if we want an errorof about 1\% units (the exp has to be about 100)in the last referred equation] gives:
  $\gamma\approx3$
  \begin{equation}
    \gamma=3
    \end{equation}
\end{itemize}


But Condition 2 (\eqref{eq:3})gives also:

$$\alpha=2\beta+2\cdot e^{-1.5\cdot3}\Longrightarrow$$
$$2\beta-\alpha=\beta-1=0.011\Longrightarrow$$
\begin{equation} \beta=1.011\end{equation}

  And Finaly we got the function:
\begin{equation}f(x)=\frac{2.011}{(1.011+e^{-3(x-1.5)})}\end{equation}






\begin{tikzpicture}
\begin{axis}[grid=both,xmax=3.25,ymax=2.5]
\addplot[blue,domain=0.1:3,samples=300]  {2.011/(1.011 + exp(-3*(x-1.5)))};
\end{axis}
\end{tikzpicture}


\end{document}

The above code generates this plot without using pgfplots or a formula, but with pure tikz curves:

enter image description here

And this after a mathematical analysis and a resulting formula:

enter image description here

Both codes (if you don't want to search all the above) are here:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}


\begin{center}
  \begin{tikzpicture}[scale=2.5]
    \draw[->,thick] (-0.2,0)--(3.7,0);%x axis
    \draw[->,thick] (0,-0.2)--(0,2.7);%y axis
    \foreach \y in {0,0.5,...,2.5}{
      \draw[-,thin] (0.,\y)--(3.5,\y);
      \node[left] at (0,\y) {\y};
    }
    \foreach \x in {0,0.5,...,3.5}{
      \draw[-,thin] (\x,0)--(\x,2.5);
      \node[below] at (\x,0) {\x};
    }
  \draw[-,blue!30!green] (0,0)to[out=5,in=225](1.5,1);
  \draw[-,blue!30!green] (1.5,1)to[out=45,in=185](3,2);
\end{tikzpicture}

\begin{tikzpicture}
\begin{axis}[grid=both,xmax=3.25,ymax=2.5]
\addplot[blue,domain=0.1:3,samples=300]  {2.011/(1.011 + exp(-3*(x-1.5)))};
\end{axis}
\end{tikzpicture}
\end{center}

\end{document}

Conclusion:

As you can see, the math needed, (even if the "type" of the formula is "almost known") are sometimes more complex that a simple latex user background and other times can be simple enough. So, if you really want to "extrtact" the actual formula... such questions are somehow offtopic and could be minegrated here: https://math.stackexchange.com/

But you (almost) always have the ability to use a number of curves like done above on first approach and get a result close to what you expect.

2

I know that you may not like this answer, but IMHO your procedure is a bit too complicated. So far I have always been able to produce reasonably close approximations by

  • using elementary functions such as sin, cos, tan, exp etc.

  • the to[in=...,out=...] syntax, which you also mention,

  • adding some transformations (and yes, sometimes the polar transformation of the TikZ manual can be handy).

The function in your input looks awfully like a stretched (1-cos) function.

\documentclass[tikz,border=3.14pt]{standalone}
\begin{document}
\begin{tikzpicture}[>=latex]
    \draw (0,0) grid[step=0.5] (3.5,2.5);
    \draw [->] (0,0) --(3.7,0) node[below]{$x$};
    \draw [->] (0,0) --(0,2.7) node[left]{$y$};
    \draw[blue,thick] plot[variable=\x,domain=0:3] ({\x},{1-cos(deg(\x)*pi/3)});
\end{tikzpicture}
\end{document}

enter image description here

I am posting this merely to provide an alternative to your answer.

11
  • Thanks, the idea of the question was to be a point of reference in "ploting" questions like the linked in the question. I just used his (provided) formula to show that it is (more) a math than a latex question except if he can accept answers without the math part like my first approach... Thanks (+1). I suppose I will leave the question as a discussion [without accepting one specific answer] ... may be it has to move at meta... Don't really know... but I think it is a useful question-answer... for such cases.
    – koleygr
    Commented Apr 12, 2018 at 15:53
  • @koleygr Well, this is probably a matter of taste. It would be even simpler to draw the figure with, say, inkscape. But I always thought that the point of LaTeX is to provide means to typeset text with scientific content. Therefore I'd like to argue that it does make sense to also assume some very basic knowledge of high school math.
    – user121799
    Commented Apr 12, 2018 at 15:58
  • You have to see the linked question to understand my point. Given a hand-drawn image (as did there) you can only use the first way and will never be sure about some not obvious (math-physics) properties of the curve... Then of course you can use any method you want but sometimes you have to give the real function or its family or some specific properties... Of course latex is used (most) for scientific reasons but this can not be a request... I have seen many plotting questions from people that can't draw a line of 45 degrees by using points...
    – koleygr
    Commented Apr 12, 2018 at 16:07
  • 1
    @koleygr This can now go on forever, but I'll stop with the beginning of the very first sentence of your question: "This post is my help to beginners in LaTeX that are trying to plot functions ...". Both my answer and my comments here are triggered by this statement.
    – user121799
    Commented Apr 12, 2018 at 16:29
  • 1
    @koleygr Wouldn't it be better if you appended all these statements and disclaimers to your post rather than this discussion? And could we please stop this discussion now? I have said everything that I wanted to say, and if you want to say more you can always revise your posts.
    – user121799
    Commented Apr 12, 2018 at 16:32
1

In case if we don't know the formula, one can use to[in=...,out=...]. Another possibility is to use Bezier curves.

\documentclass[12pt]{article}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}





\pgfplotsset{cartesian/.style={%
            grid = both,
            minor tick num = 5,
            minor grid style = {line width=.1pt,draw=gray!10},
            axis lines = middle,
            axis line style={-stealth},
            xlabel style={below right},
            ylabel style={above left},
            xtick = {0,0.5,...,3.5},
            ytick = {0,0.5,...,2.5},
            xmin = 0,
            xmax =  3.5,
            ymin = 0,
            ymax =  2.5,
            width=1\linewidth,
            height=1\linewidth,
}}          

%===============================================================================
\begin{document}
\noindent
\begin{tikzpicture}
    \begin{axis}[cartesian]
        \draw[green!50!black] (0,0) to[out=0,in=185] (3,2);
    \end{axis}
\end{tikzpicture}


\end{document}

enter image description here

3
  • Hi, Please add some words about your approach, so that people can gain from your answer. I am not good at pgfplots (haven't used enough) and can not really understand all of your code (For example why doamin={-6:6}? if the function is between {0,3}?) I think some words can help...
    – koleygr
    Commented Apr 12, 2018 at 15:56
  • @koeygr I was cleaned my code a bit. Unfortunantly, I was late with words in my answer, and I completely agree with marmot in case of using to[in=...,out=...] Commented Apr 12, 2018 at 16:07
  • I see just the same function as mine... And the question is more about the curve and not the grid (that is your change in my code and you created with another way)... Also I don't know if you disagree somewhere with me (because of your last comment)... because I didn't disagreed with someone about "to[in=..., out=...]" But it's ok. Anyway, I think If you had used "Bezier curves" as you mentioned above I think your answer would provide an alternative and thus would be useful for future users who cant find the function's formula
    – koleygr
    Commented Apr 12, 2018 at 16:55
1

I'm usually just plotting a set of points as I found that an easier approach then trying to figure out a mathematical function which would end up right - or trying to draw bezier lines.

Now you might be wondering how to get the point data. For that I use the Engauge Digitizer tool (I'm just a user, not the creator). With some practice you can even use a hand scribble, scan it and generate points to plot.

If you are using this approach your compilation time might end up getting huge which is why I use an externalize approach for that, so the figures are being built as PDF only when the context changes and not every time.

I'm currently not able to test if I got everything in working order, but here is an outline of how it looks (maybe I can provide a better example later):

enter image description here


  1. Generate a data file with Engauge Digitizer (in this example "elekguete.txt") looking somthing like this:

elekguete.txt:

0 1521.74
2 882.31
3 806.24
4 749.92
5 558.59
6 438.69
7 424.90
8 361.17
9 346.71
10 311.49
11 287.47
12 273.80
13 261.48
14 246.07
15 229.86
16 212.86
17 205.15
18 196.04

Then the file I'm using to generate the plot looks like this (of course to generate just a plot of the curve, you don't need the mathematical model):

\tikzsetnextfilename{elekguete}
\begin{tikzpicture}
        \begin{axis}[
        width = 0.7\textwidth,
        height = 0.35\textheight,
        grid=major,
        xmin = 0,
        xmax = 18,
        xlabel=Eintauchtiefe in \si{\mm},
        ylabel=elektrische Güte,
        legend style={anchor = north east, at={(0.98,0.98)}}
        ]

        \addplot[color=red,mark=x, only marks] table[x index=0,y index=1,header=false]
                {elekguete.txt};

        \addplot+[color=blue, no marks, domain=0:18]{204.23 +
        1290.7*exp(x/(-3.8778))};

        \end{axis}

\end{tikzpicture}

While using these settings, which are bloated now (I took it out of a document right now, like I said, I'll hopefully find time to produce a better, more minimal working example):

\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{shapes}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{calc}
\usetikzlibrary{shapes.symbols}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{scopes}
\usetikzlibrary{decorations.shapes}
\usepackage{pgfplots}
\pgfplotsset{width=0.7\textwidth}
\pgfkeys{/pgf/number format/.cd,fixed,use comma,1000 sep={\,}}

\usetikzlibrary{external}
\tikzsetexternalprefix{externalize/}
\tikzset{external/system call={lualatex \tikzexternalcheckshellescape --source-specials -interaction=batchmode -jobname "\image" "\texsource"}}
\pgfkeys{/tikz/external/only named={true}}
\tikzexternalize

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .