Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Question

Is there a way to include mathematical expressions in PGFPlots, for example, [domain=1/3:e^5/3]?

PGFPlots is fairly useful, however the ability to put mathematical expressions directly into Tikz makes life much easier.

The only way around this problem that I know of is to define a bunch of constants above the before entering the axis environment. I find this a little obnoxious.

enter image description here

MWE

\documentclass{memoir}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{amsmath}

\usetikzlibrary{calc, positioning}

\begin{document}

\begin{tikzpicture}[domain=1/3:e^5/3,x=0.1cm, scale=1]

    % Axes
    \draw[help lines]   (-0.2 cm,0) -- (e^5/3+0.2,0) node[right] {$x$};
    \draw[help lines]   (0,-0.2) -- (0,6) node[above] {$y$};
    \draw[gray, thick]  (e^5/3,5) -- (-0.075/0.1,5) node[left] {$y=5$};
    \draw[gray, thick]  (e^5/3,4) -- (-0.075/0.1,4) node[left] {$y=4$};

    % Curves
    \draw[blue, thick] plot[id=lnx] (\x,{ln(3*\x)}) node[right] {$\ln 3x$};
\end{tikzpicture}

\end{document}
share|improve this question
2  
you can directly write \addplot[domain=1/3:e^5/3] {ln(3*x)} in pgfplots: it applies the math parser. That said, there are still lots of places where the math parser should be invoked... a relic of times when the floating point unit was unavailable. –  Christian Feuersänger Jul 5 '13 at 16:18
    
@ChristianFeuersänger: It seems like this doesn't work when the axis is logarithmic. xmode=log,domain=1/3:e^5/3 leads to Could not parse input '1/3' as a floating point number. Is there a way around that? –  Jake Jul 5 '13 at 16:22
    
@ChristianFeuersänger Yes, that works for the domain. However, try to write \begin{semilogyaxis}[xmin=-1, xmax=e^5/3+5,] ... and you'll run into issues! This is likely one of those places where the math parser could stretch its legs a little. –  JDG Jul 5 '13 at 16:29
    
@ChristianFeuersänger Anyhow, pgfplots is so useful that I am using it, albeit with tons and tons of \pgfmathsetmacro expressions. Hehehe –  JDG Jul 5 '13 at 16:31
1  
@Jake and JDG: the next stable version will come with support for the math parser in axis limits and log domains (already committed to git repo). –  Christian Feuersänger Jul 6 '13 at 18:58
show 4 more comments

2 Answers 2

up vote 6 down vote accepted

You can define a slightly modified version of the domain key to save yourself the trouble of manually parsing the expressions first. If you include the following snippet in your document, you'll be able to type domain*=1/3:e^5/3 even when you're using logarithmic axes (and similarly for xmin, ymax, etc.):

\makeatletter
\pgfplotsset{
    domain*/.code args={#1:#2}{
        \pgfmathsetmacro\pgfplots@lower{#1}
        \pgfmathsetmacro\pgfplots@upper{#2}
        \pgfplotsset{domain=\pgfplots@lower:\pgfplots@upper}
    },
    xmin*/.code={
        \pgfmathparse{#1}
        \pgfplotsset{xmin=\pgfmathresult}
    },
    xmax*/.code={
        \pgfmathparse{#1}
        \pgfplotsset{xmax=\pgfmathresult}
    },  
    ymin*/.code={
        \pgfmathparse{#1}
        \pgfplotsset{ymin=\pgfmathresult}
    },
    ymax*/.code={
        \pgfmathparse{#1}
        \pgfplotsset{ymax=\pgfmathresult}
    }
}
\makeatother

Your plot could be implemented in PGFPlots using something like this:

\documentclass{memoir}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{amsmath}

\usetikzlibrary{calc, positioning}

\begin{document}

\makeatletter
\pgfplotsset{
    domain*/.code args={#1:#2}{
        \pgfmathsetmacro\pgfplots@lower{#1}
        \pgfmathsetmacro\pgfplots@upper{#2}
        \pgfplotsset{domain=\pgfplots@lower:\pgfplots@upper}
    }
}
\makeatother

\begin{tikzpicture}
\begin{axis}[
    xmode=log,
    log ticks with fixed point,
    axis lines*=left,
    xlabel=$x$,
    every axis x label/.style={
        at={(rel axis cs:1,0)},
        anchor=west
    },
    ylabel=$y$,
    every axis y label/.style={
        at={(rel axis cs:0,1)},
        anchor=south
    },
    ymin=0,
    xmin=0.1,
    enlarge x limits=false,
    domain*=1/3:e^5/3,
    ytick={0,4,5},
    ymajorgrids,
    yticklabel={$y = \pgfmathprintnumber{\tick}$},
    clip=false
]
\addplot [thick, red] {ln(3*x)} node [anchor=west] {$\ln 3x$};
\end{axis}
\end{tikzpicture}

\end{document}
share|improve this answer
    
This is a great piece of code. However, I tried out the solution and it works in some cases, but does not work in others. For example, I received an error when typing xmin=1/3. In that case, one would still need to make use of commands like \pgfmathsetmacro. –  JDG Jul 5 '13 at 18:41
1  
@JDG: Well, it only works as a replacement for the domain key, of course. It doesn't do anything to xmin, or ymax, etc. You can define similar code snippets for those: \pgfplotsset{xmin*/.code={\pgfmathparse{#1}\pgfplotsset{xmin=\pgfmathresult}} and then use xmin*=1/3 instead of xmin=1/3. I've edited my answer. –  Jake Jul 5 '13 at 18:44
add comment

Pgfplot Workaround

As an answer, here's the Pgfplot workaround I mentioned, which defines variables using \pgfmathsetmacro before the axis environment. The advantage of this workaround is that it is extremely easy to understand and can be reused easily for similar graphs, which is useful for Calculus 1–3-level homework problems.

enter image description here

MWE

\documentclass{memoir}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepackage{amsmath}

\usetikzlibrary{calc, positioning}

\begin{document}

\begin{tikzpicture}[scale=1.5]

\pgfmathsetmacro\xDomainMin{0}
\pgfmathsetmacro\xDomainMax{e^5/3*3}
\pgfmathsetmacro\xMin{-10}
\pgfmathsetmacro\xMax{\xDomainMax+\xDomainMax/50}
\pgfmathsetmacro\yMin{-1}
\pgfmathsetmacro\yMax{6}
\pgfmathsetmacro\xRotation{(e^5/3+5)/2}
\pgfmathsetmacro\yRotation{0}

\begin{semilogyaxis}[   
    axis x line=center,
    axis y line=center,
    axis z line=center,
    xlabel={$x$},
    ylabel={$y$},
    zlabel={$z$},
    axis line style=help lines,
    gray,
    every axis/.append style={font=\tiny},
    width=10cm,
    height=8cm,
    domain=\xDomainMin:\xDomainMax,
    xmin=\xMin, xmax=\xMax,
    ymin=\yMin, ymax=\yMax,
    xtick=\empty,
    ytick={4,5},
    yticklabels={$y=4$,$y=5$},
    area style,
]
    \addplot[id=five, gray, very thin, fill=blue, opacity=0.1] {5} \closedcycle;
    \addplot[id=lnx, white, very thin, mark=none, samples=200, fill=white,]
        {ln(3*x)}\closedcycle;
    \addplot[id=four, gray, very thin, fill=white] {4} \closedcycle;
    \addplot[id=five, gray, very thin,] {5};
    \addplot[id=five, white, very thin, fill=white,
            domain=\xDomainMax-0.1:\xDomainMax+1] {5} \closedcycle;
\addplot[id=lnx, blue, very thin, mark=none, samples=200,]
        {ln(3*x)} node [right]{\color{blue}$\ln x$};

\draw[->,gray, thick]
    (axis cs:6,4.5) arc (-30:-150:8 pt);


\end{semilogyaxis}

\end{tikzpicture}

\end{document}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.