10

I am writing my thesis in behavioural economics and have to draw individual discount functions, I did the following graph with stata, but would love to have it with tikz.

enter image description here

I played around in tikz and got this so far:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[domain=-1:5,samples=400]
        \addplot+[mark=none] {1-(1-0.7*0.8)*(x+1)};
        \addplot+[mark=none] {0.7*0.8^(x+1)};
    \end{axis}
\end{tikzpicture}
\end{document}

which leads to this output:

enter image description here

Sadly my deadline is very soon. Could anyone help me with following fixes?

  1. the range of the y-axis should be from 0 to 1

  2. the range of the x-axis should be from 0 to 5, AND the x-value showed should be the true value of the function +1

  3. the functions shouldn't cross, just touch i.e.

    \addplot+[mark=none] {1-(1-0.7*0.8)*(x+1)};
    

    from x=-1 to 0 (showed values: 0 to 1)

     \addplot+[mark=none] {0.7*0.8^(x+1)};
    

    from x=0 to 4 (showed values: 1 to 5)

  4. Both functions should have the same colour (black)

![enter image description here][1]

1
  • 2
    You can draw the function 1 using the axis coordinate system: \draw (axis cs:x=0,y=1) -- (axis cs:x=5, y=1);.
    – user10274
    Mar 19 '14 at 15:52
10

You can simply add the domain specification to each function to restrict the shown part of the function. To display different values on the x-axis simply shift it one to the right by removing the +1 from your function. Color specification can be added to the \addplot to set it all to black, and finally if you want to be sure no data outside the y domain 0:1 is displayed use restrict y to domain=0:1.

Edit: added axis labels the pgfplots way.
Edit 2: Added second plot and legend. Note the \addlegendentry simply adds entries in the order of the \addplots, and sees the two parts as separate plots, so the easiest way is to first plot all the first parts of each plot, set up the legend, and then plot the second part of each plot.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        domain=0:5,
        samples=400,
%        ymin=-0.1,   % Uncomment if 0 should really be shown,
%        ymax=1.1,    % leave commented to let pgfplots figure out the exact y domain
        restrict y to domain=0:1,
        xlabel={Month},
        ylabel={Value of Discount Function},
        ]
        \addplot+[mark=none,black,domain=0:1] {1-(1-0.7*0.8)*(x)};
        \addplot+[mark=none,blue,domain=0:1] {0.8-(1-0.7*0.8)*(x)};
        \addlegendentry{A}
        \addlegendentry{B}
        \addplot+[mark=none,black,domain=1:5] {0.7*0.8^(x)};
        \addplot+[mark=none,blue,domain=1:5] {0.7*0.8^(x)-0.2};
    \end{axis}
\end{tikzpicture}
\end{document}

Updated plots

2
  • Thank you very much ! Could you tell me one additional thing? I added a second function(since I have to compare two groups) How do I add a legend?(I uploaded a picture of it). I tried \addlegendentry{$\delta$} after a adplot but it doesn't give me the colour of the line. Mar 19 '14 at 16:55
  • I updated my answer, since you didn't provide the function of the second plot I simply shifted the first 0.2 down ;)
    – hugovdberg
    Mar 19 '14 at 17:04
4

Here’s the code:

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}

\usepackage{rotating}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[samples=400,
        ymin = -0.1,
        ymax = 1.1,
        xmin = -0.3,
        xmax = 5.3]
        \addplot+[mark=none, domain=0:1, black] {1-(1-0.7*0.8)*x};
        \addplot+[mark=none, domain=1:5, black] {0.7*0.8^x};
    \end{axis}

    \draw (3.5, -0.7) node [below] {Month};

    \draw (-0.9, 2.7) node [left] {\rotatebox{90}{Value of Discount Function}};

\end{tikzpicture}
\end{document}

and the output:

enter image description here

What I've done:

  1. Added the keys ymin and ymax to the axis environment: these set the limits of the y-axis. I added a slight amount of padding to match the Stata graph, but you could easily set these to exactly 0 and 1 if you preferred.

  2. Added the keys xmin and xmax to set the limits of the x-axis. The extra horizontal padding was determined mostly by eye, and by tweaking.

    To get the function translated by +1, I simply replaced x+1 by x in the two addplot definitions. (I wasn’t entirely sure what you meant by this, but judged it from the Stata graph.)

  3. Rather than setting the domain as an option to axis, you can supply it as a separate argument to addplot. So I added domain=0:1 and domain=1:5 to the two plotting functions, so you only get the single line. (Note the translation by +1 to accommodate the axis shift.)

  4. Add the argument black to both addplot commands.

I also added two \draw commands to place and rotate the axis labels. (Again, mostly done by eye, although I ~think there’s a nicer way to do it.)

2
  • There is a nicer way to add the axis labels, using the built in [x|y]label options to the axis environment. This also makes sure the labels are placed consistently independent of any changes to your axis, or when copy pasting an environment for another figure ;)
    – hugovdberg
    Mar 19 '14 at 16:10
  • 1
    Also, there is no need to set the xmin, xmax, and ymax if the domain of the functions is restricted like this, only the ymin option might be wanted if the 0 is actually to be shown.
    – hugovdberg
    Mar 19 '14 at 16:17
2

The solution from hugovdberg as well as from alexwlchan have the downside that they both draw the piecewise function piecewise which has in general some disadvantages like

  • legend issues when you need to draw more than one function in a plot or
  • one has to keep track of styles.

(Borrowed these from JM114516.)


If you know the two function parts of the piecewise function but don't know where the intersection point is, you can simply use the max function (in this case) to draw the function in one \addplot command ...

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    \pgfplotsset{
        % use at least this compat level
        % to improve positioning of the axis labels
        compat=1.3,
    }
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            % set ymin value
            ymin=0,
            % in which domain should the expression be calculated ...
            domain=0:5,
            % ... with how many samples?
            samples=400,
            % add axis labels
            xlabel={Month},
            ylabel={Value of Discount Function},
            % don't show markers
            no markers,
        ]
        % piecewise function part 1
            \addplot [black!25,very thick] expression {
                    1-(1-0.7*0.8)*x
            };
        % piecewise function part 2
            \addplot [black!25,very thick,dashed] expression {
                    0.7*0.8^x
            };
        % piecewise function combined
            \addplot [red] expression {
                max(
                    1-(1-0.7*0.8)*x,
                    0.7*0.8^x
                )
            };

            \legend{
                ,           % <-- empty string to ignore this `\addplot'
                ,
                discount function,
            }
        \end{axis}
    \end{tikzpicture}
\end{document}

image showing the result of above 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.