0

I am trying to recreate the attached figure using PGF plots. Is there an easier way to do this? Is there a way to draw or create functions similar to this without having to necessarily know the equation of the function? I have tried using the hobby package and estimate points of the curve, but had no luck.

I know I could screen shot the pic, but it does not look as good. I would really like to learn how to do this more efficiently. I am trying to use quadratic equations, but as you can see my figure is incomplete. I hope it is possible. I also would love to know how to draw the f(x) label node with the arrow.

Any help would be appreciated.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{graphics}
\usepackage{graphicx}
\usetikzlibrary{hobby}
\pgfplotsset{compat=newest}
\tikzset{point/.style={circle,draw=black,inner sep=0pt,minimum size=3pt}}
\usetikzlibrary{arrows.meta}
\usepackage[labelformat=empty]{caption}

\begin{document}

\begin{figure}
    \centering
        \begin{tikzpicture}
                \begin{axis}[grid style={gray!50}, thick,
                    xlabel={\(x\)},
                    ylabel={\(y\)}, xmin=-4,xmax=6,ymin=-5,ymax=5,
            every axis plot/.append style={ultra thick},
            axis y line=center,
            axis x line=center,
            axis line style={Triangle-Triangle},
             ticklabel style={font=\small,fill=white},
             yticklabels=\empty,
              ytick=\empty
            ]
            \addplot[thick,samples=1000,domain=-3:-2]{-2*(x+3)^2+2};
            \addplot[thick,samples=1000,domain=0:2]{-(x-1)^2};

            \addplot[thick,samples=1000,domain=-2:-1]{.5(x+1)^2-2};
            \draw[thick, dashed] (-3,0)--(-3,2);

            \addplot[thick,samples=1000,domain=3:5]{-(x-5)^2+2};
            \draw[thick, dashed] (-3,0)--(-3,2);
            
            \draw[thick,dashed] (5,0)--(5,2);
            \draw[thick,dashed] (3,0)--(3,-3);
            \draw[thick,dashed] (-1,0)--(-1,-2);
            
             \end{axis}

        \end{tikzpicture}
    \caption{}
\end{figure}
\end{document}

Intended:

enter image description here

As-is:

as-is


UPDATE: SOMEONE CLOSED THIS, NOT SURE WHY. HERE IS A SOLUTION FROM A COLLEAGUE, STEFAN.

you could include the original image as a node, draw a grid to see the coordinates, then choose as many coordinate values as possible and draw a smooth plot, then remove the image node:

\documentclass[tikz,border=10pt]{standalone}
\begin{document}
\begin{tikzpicture}
  %\node[opacity=0.5] at (2.8,1.2) {\includegraphics{screenshot}};
  \draw[thin,dotted] (-8,-5) grid (12,3);
  \draw[->] (-8,0) -- (13,0);
  \draw[->] (0,-5) -- (0,7);
  \draw plot [smooth,tension=0.7] coordinates {
    (-6.3,2.5) (-5.4,2) (-4.7,1) (-4,-0.5) (-3,-3) (-2,-3.6)
    (-1,-3) (0,-1.8) (1,-0.5) (2,0) (3,-0.5) (4,-1.8) (5,-3.2)
    (6.1,-4.1) (7,-3.2) (8,-0.6) (9,1) (10,2) (10.5,2.1)
  };
\end{tikzpicture}
\end{document}

tikzresult

6
  • Where is figure?
    – Zarko
    Dec 9, 2022 at 1:39
  • Sorry, it is up there now!
    – Nick B
    Dec 9, 2022 at 2:12
  • 4
    Hm, this seem not to be LaTeX problem but math: how to define function showed on image.
    – Zarko
    Dec 9, 2022 at 3:10
  • Looks a little like the one here
    – Roland
    Dec 9, 2022 at 3:32
  • You can answer your own question :) So instead of adding a possible solution to the question post, I suggest you post an answer with that code. Dec 11, 2022 at 17:33

4 Answers 4

0

With all your preamble and this code:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{graphics}
\usepackage{graphicx}
\usetikzlibrary{hobby}
\pgfplotsset{compat=newest}
\tikzset{point/.style={circle,draw=black,inner sep=0pt,minimum size=3pt}}
\usetikzlibrary{arrows.meta}
\usepackage[labelformat=empty]{caption}

\begin{document}
    
    \begin{figure}
        \centering
        \begin{tikzpicture}
            \begin{axis}[grid style={gray!50}, thick,
                xlabel={\(x\)},
                ylabel={\(y\)}, xmin=-4,xmax=6,ymin=-5,ymax=5,
                every axis plot/.append style={ultra thick},
                axis y line=center,
                axis x line=center,
                axis line style={Triangle-Triangle},
                ticklabel style={font=\small,fill=white},
                yticklabels=\empty,
                ytick=\empty
                ]
                \addplot[cyan,thick,samples=1000,domain=-3:5]{cos(3*x*180/pi)-2*(sin(x*180/pi))^2};         
            \end{axis}
            
        \end{tikzpicture}
        \caption{Guess the equation of the function}
    \end{figure}
\end{document}

You have this output:

enter image description here

But we need to know the equation of the function You need to plot.

2
  • 1
    I can plot equations, that is not a problem. I don't have the equation of the function. I was wondering if it was possible using (hobby) or other package do get a general sketch of this curve without trying to guess what it is. This is from an AP exam and equation is not included.
    – Nick B
    Dec 9, 2022 at 10:17
  • From my colleague Stefan, \documentclass[tikz,border=10pt]{standalone} \begin{document} \begin{tikzpicture} %\node[opacity=0.5] at (2.8,1.2) {\includegraphics{screenshot}}; \draw[thin,dotted] (-8,-5) grid (12,3); \draw[->] (-8,0) -- (13,0); \draw[->] (0,-5) -- (0,7); \draw plot [smooth,tension=0.7] coordinates { (-6.3,2.5) (-5.4,2) (-4.7,1) (-4,-0.5) (-3,-3) (-2,-3.6) (-1,-3) (0,-1.8) (1,-0.5) (2,0) (3,-0.5) (4,-1.8) (5,-3.2) (6.1,-4.1) (7,-3.2) (8,-0.6) (9,1) (10,2) (10.5,2.1) }; \end{tikzpicture} \end{document}
    – Nick B
    Dec 11, 2022 at 11:48
0

As you are looking for a systematic approach, here's a modelers approach.

Describing your inteded result

intended

If you neglect details for a moment, at least in the middle the curve seems to be close to a sine-wave. It may be even shifted by -1 units.

So what comes to mind is trying one or a combination of:

  • applying an offset, depending on x
  • applying a modulation, which is >= 1, and asymmetric
  • asymmetric means: (y-1) = a x, x>0; -b x, x<0; a>0,b>0

Trying those variants

The dashed teal is for reference.

The blue one is the shifted sine, with some adjustment of its frequency. Please note, trig format=rad, swithces to radians, but changes the arrows for the axes for a reason.

result

The orange one adds a linear (=symmetric) decreasing offset. If it could switch slope, as indicated above, chances are fine for a good match.

pgfplots may or may not provide a way to use step-functions within the equations. A poor mans approach is to use two exponentials, which you can tweak as needed exp(-x) + exp(x), because it has the basic characteristics needed:

    % ~~~ shifted sine approximation times asymmetric factor ~~~
    \addplot[red,thin,samples=60,domain=-3:5 ]{
        (sin(x*5.3/pi) * (0.8 + 0.06* exp(-x) + 0.06*exp(x/2)))-1
        %       ^          ^      ^         ^    ^         ^    ^
        % 7 tweaking parameters
    };

Kindly watch the multiplication inside between the sine and the compound step-functions. This model provides 7 parameters for adjustments.

As you can see, my trial&error for setting the 7 parameters is not that bad and obviously provides some potential for better results. You may want to run an optimizer on it outside of LaTeX.

0

As you are looking for a methodical approach, here's one via polynomials.

Restricting the polynomial

It shall provide 5 extrema (maxima and minima), so its derivative needs to provide 5 zeros (at least), which means it must be a pol. of order 6 (at least).

It shall provide 3 zeros, which a 3rd order poly would do (at least).

You could provide more restrictions and at some point derive an analytical solution, which most likely will be underdertmined, i.e. provides degrees of freedom to exploit.

However, this is lengthy, though nice for some students course ...

Cheap trick

So, let's use a cheap trick and use a program, which does the fit right away.

EXCEL might just do THIS job, as it allows 6th order polys:

result

As intrinsic to polynomials they tend to become less precise at the domain limits. To compensate, a higher order fit might be better. But perhaps it's good enough.

pgfplots

No big deal - in theory: copy the equation.

result

%\documentclass{article}
\documentclass[10pt,border=3mm,tikz]{standalone}
%\usepackage{tikz}
\usepackage{pgfplots}
%\usepackage{graphics}
%\usepackage{graphicx}
%\usetikzlibrary{hobby}
\pgfplotsset{compat=newest}
%\tikzset{point/.style={circle,draw=black,inner sep=0pt,minimum size=3pt}}
\usetikzlibrary{arrows.meta}
%\usepackage[labelformat=empty]{caption}

\begin{document}

%\begin{figure}
%    \centering
 \begin{tikzpicture}
    \begin{axis}[
        grid style={gray!50},
        thick,
        xlabel={\(x\)},
        ylabel={\(y\)},
        xmin=-4,xmax=6,ymin=-5,ymax=5,
         every axis plot/.append style={ultra thick},
        axis y line=center,
        axis x line=center,
        axis line style={Triangle-Triangle},
        ticklabel style={font=\small,fill=white},
        yticklabels=\empty,
        ytick=\empty,
    ]
    % ~~~ reference: very simple approximation through characteristic points ~~~
    \addplot[teal,thin,dashed ]coordinates{
        (-3,1.2) (-2,0) (-1,-1.7) (0,-.9)
        (1,0) (3,-2) (4,0) (5,1)
    };
    
    % ~~~ from polynomfit in EXCEL ~~~
    \addplot[blue,thin,samples=60,domain=-3:5 ]{
        - .0069*x^6
        + .0403*x^5 
        + .0839*x^4 
        - .5763*x^3 
        - .1478*x^2 
        + 1.3904*x 
        - .8284
    };

    \end{axis}

 \end{tikzpicture}
%    \caption{}
%\end{figure}
\end{document}
0

As you are looking for a methodical approach, here's one, which artists or graphic designers might chose. It seems to be close to the hobby-approach.

By its very nature it's a trial&error approach, tweaking whatever parameters you have at hand with visual control.

Get the coordinates

Either you guess the coordinates, which isn't bad to do, or you calculate them from pixel-data:

  • identify known lengths
  • fit them to obtain a scaling factor (here: 0.0084 units/pixel)
  • calculate the missing ones from lengths in pixels

scalingfactor

Draw and refine

I show a few approaches in one diagram, while preserving the pgfplots-approach:

results

Dashed and teal is for reference; delete or comment out later:

    % ~~~ reference: very simple approximation through characteristic points ~~~
    \addplot[teal,thin,dashed ]coordinates{
        (-3,1.2) (-2,0) (-1,-1.7) (0,-.9)
        (1,0) (3,-2) (4,0) (5,1)
    };

If you add smoothing, and certainly tension, the result isn't that bad at all, and could be improved by adding a frew more points where needed: \addplot[teal,thin,smooth ]coordinates{...

Within the axis environment you can also draw with Tikz, and it may be suitable, to use the axis coordinate system. First, the reference as dotted red, and shifted:

    % ~~~ let's repeat the same with Tikz in the axis cs ~~~~~~~~
    \draw[red, dotted, yshift=1.8cm]    % shifted for visibility
        (axis cs: -3,1.2)   -- (axis cs: -2,0)  --  
        (axis cs: -1,-1.7)  -- (axis cs: 0,-.9) -- 
        (axis cs: 1,0)      -- (axis cs: 3,-2)  -- 
        (axis cs: 4,0)      -- (axis cs: 5,1);

Next, graphic designers would introduce Bezier curves and start adjusting all those handles manually, and perhaps add a few more points. Tikz provides these too via controls, but a) it's harder to visualize, b) the points often are far away hence increase the plot area. So I prefer replacing the -- by to[out=,in=] and specify all angles:

    % ~~~ let's control output and input angles ~~~~~~~~
    \draw[red, yshift=2.3cm]    % shifted for visibility
        (axis cs: -3,1.2)   to[out=0,in=130]    (axis cs: -2,0)     
                            to[out=-70,in=180]  
        (axis cs: -1,-1.7)  to[out=0,in=210]    (axis cs: 0,-.9)    
                            to[out=40,in=180] 
        (axis cs: 1,0)      to[out=0,in=180]        (axis cs: 3,-2) 
                            to[out=0,in=240] 
        (axis cs: 4,0)      to[out=70,in=180]       (axis cs: 5,1);

I left some imperfections, also to indicate, that the left and right side might benefit from an additional intermediary point, too. Or shifting one or two may be all you need.


%\documentclass{article}
\documentclass[10pt,border=3mm,tikz]{standalone}
%\usepackage{tikz}
\usepackage{pgfplots}
%\usepackage{graphics}
%\usepackage{graphicx}
%\usetikzlibrary{hobby}
\pgfplotsset{compat=newest}
%\tikzset{point/.style={circle,draw=black,inner sep=0pt,minimum size=3pt}}
\usetikzlibrary{arrows.meta}
%\usepackage[labelformat=empty]{caption}

\begin{document}

%\begin{figure}
%    \centering
 \begin{tikzpicture}
    \begin{axis}[
        grid style={gray!50},
        thick,
        xlabel={\(x\)},
        ylabel={\(y\)},
        xmin=-4,xmax=6,ymin=-5,ymax=5,
         every axis plot/.append style={ultra thick},
        axis y line=center,
        axis x line=center,
        axis line style={Triangle-Triangle},
        ticklabel style={font=\small,fill=white},
        yticklabels=\empty,
        ytick=\empty
    ]
    % ~~~ reference: very simple approximation through characteristic points ~~~
    \addplot[teal,thin,dashed ]coordinates{
        (-3,1.2) (-2,0) (-1,-1.7) (0,-.9)
        (1,0) (3,-2) (4,0) (5,1)
    };
    
    % ~~~ same, smoothed ~~~
    \addplot[teal,thin,smooth ]coordinates{
        (-3,1.2) (-2,0) (-1,-1.7) (0,-.9)
        (1,0) (3,-2) (4,0) (5,1)
    };
    
    % ~~~ let's repeat the same with Tikz in the axis cs ~~~~~~~~
    \draw[red, dotted, yshift=1.8cm]    % shifted for visibility
        (axis cs: -3,1.2)   -- (axis cs: -2,0)  --  
        (axis cs: -1,-1.7)  -- (axis cs: 0,-.9) -- 
        (axis cs: 1,0)      -- (axis cs: 3,-2)  -- 
        (axis cs: 4,0)      -- (axis cs: 5,1);
    
    
    % ~~~ let's control output and input angles ~~~~~~~~
    \draw[red, yshift=2.3cm]    % shifted for visibility
        (axis cs: -3,1.2)   to[out=0,in=130]    (axis cs: -2,0)     
                            to[out=-70,in=180]  
        (axis cs: -1,-1.7)  to[out=0,in=210]    (axis cs: 0,-.9)    
                            to[out=40,in=180] 
        (axis cs: 1,0)      to[out=0,in=180]        (axis cs: 3,-2) 
                            to[out=0,in=240] 
        (axis cs: 4,0)      to[out=70,in=180]       (axis cs: 5,1);
           
    \end{axis}

 \end{tikzpicture}
%    \caption{}
%\end{figure}
\end{document}

You must log in to answer this question.

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