# Drawing curves and multiple y-axes in one plot with pgfplots

I'm aware of the possibility given by pgfplots to have two y-axes, one on the left and one on the right with two different scales. But I'd like to explore other ways to have multiple axes, e.g. putting a separate axis besides a given plot. I've studied the groupplot environment and tried to put a second y-axis on the left of a plot.

Here's my MWE:

\documentclass{article}
\usepackage{lmodern}
\usepackage{pgfplots}
\pgfplotsset{compat=1.3}
\usepgfplotslibrary{groupplots}
\begin{document}
\pgfkeys{
/pgf/number format/.cd,
set decimal separator={,{\!}},
set thousands separator={}
}
\pgfplotsset{
every axis/.append style = {
line width = 1pt,
tick style = {line width=1pt}
}
}
\begin{tikzpicture}
\begin{groupplot}[
group style = {
group size=3 by 1,
horizontal sep=1.3cm, vertical sep=0pt,
xticklabels at=edge bottom
},
height=5cm, width=9cm,
no markers
]
% this is the leftmost y axis
\nextgroupplot[
width=2cm,
hide x axis,
axis y line*=left,
ymin=0, ymax=10,
ytick = {0,1,...,10},
ylabel={\color{red}$y_2$}
]
% this is the red curve
\nextgroupplot[
xmin=0, xmax=10,
xlabel={$x$},
ymin=0, ymax=100,
ytick = {0,20,...,100},
ylabel={\color{blue}$y_1$}
]
% this is the blue curve
\nextgroupplot[
xshift=-8.715cm,% see above: horizontal sep=1.3cm
xmin=0, xmax=10,
ymin=0, ymax=10,
hide x axis,
hide y axis,
]
\end{groupplot}
\end{tikzpicture}
\end{document}


that produces the following result:

Q1: Why the yticks for the red curve (label $y_2$) are wrong?

Q2: is there a more neat way to shift left the last plot (red curve), instead of setting "xshift=-8.715cm" after a trial-and-error process?

-
Q1: I suppose it did not find complete axis limits (because that particular axis has no data). It probably uses [0,1] x [0,1] as fallback (which should be indicated by some warning in your log file). Provide some (arbitrary, but non-empty) x range will fix the problem: xmin=0,xmax=1 –  Christian Feuersänger Sep 4 '11 at 16:37
Q2: unless you have a specific reason for using groupplots here, I would recommend to use three separate axes instead - and shift only your (red) axis to the left. This is considerably less tedious. Groupplots are strong if the axes are closely related (for example if they share axis descriptions). But this does not seem so in your case. –  Christian Feuersänger Sep 4 '11 at 16:40
@Christian: I don't have any specific reasons to use groupplots here. How could it be done three using separate axes instead? –  agodemar Sep 4 '11 at 16:49

As discussed in my comments, here is my proposed solution without groupplots.

To summarize the comments, I replicate them here:

Q1: It really did not find complete axis limits (because that particular axis has no data), so it uses [0,1] x [0,1] as fallback (which should be indicated by some warning in your log file). Provide some (arbitrary, but non-empty) x range will fix the problem: xmin=0,xmax=1

Q2: you can provide \begin{axis}[options] ... \end{axis} several times in one picture - each time with different options and with different plots. As long as the options for dimensions (like width), positioning (at, xshift, etc), and alignment (anchor) are the same, they will be drawn on top of each other.

My proposed solution is to draw two axes completely on top of each other, and only the second y axis with an xshift.

Here is the combined approach for your MWE:


\documentclass{article}
\usepackage{lmodern}
\usepackage{pgfplots}
\pgfplotsset{compat=1.3}
\usepgfplotslibrary{groupplots}
\begin{document}
\pgfkeys{
/pgf/number format/.cd,
set decimal separator={,{\!}},
set thousands separator={}
}
\pgfplotsset{
every axis/.append style = {
line width = 1pt,
tick style = {line width=1pt}
}
}
\begin{tikzpicture}
% --- CF:  provide shared options here with pgfplotsset:
\pgfplotsset{
height=5cm, width=9cm,
no markers
}
% this is the leftmost y axis
\begin{axis}[
xmin=0,xmax=1,%--- CF
xshift=-1.8cm,%-- CF
width=2cm,
hide x axis,
axis y line*=left,
ymin=0, ymax=10,
ytick = {0,1,...,10},
ylabel={\color{red}$y_2$}
]
\end{axis}

% this is the red curve
\begin{axis}[
xmin=0, xmax=10,
xlabel={$x$},
ymin=0, ymax=100,
ytick = {0,20,...,100},
ylabel={\color{blue}$y_1$}
]
\end{axis}

% this is the blue curve
\begin{axis}[
xmin=0, xmax=10,
ymin=0, ymax=10,
hide x axis,
hide y axis,
]
\end{axis}
\end{tikzpicture}
\end{document}


-
Thanks, this is exactly the solution I was looking for. –  agodemar Sep 4 '11 at 21:31

This is the end result of what I had in mind:

\documentclass{article}
\usepackage{lmodern}
\usepackage{pgfplots}
\pgfplotsset{compat=1.3}
\usepgfplotslibrary{groupplots}
\begin{document}
\pgfkeys{
/pgf/number format/.cd,
set decimal separator={,{\!}},
set thousands separator={}
}
\pgfplotsset{
every axis/.append style = {
line width = 1pt,
tick style = {line width=1pt}
}
}
\begin{tikzpicture}
% provide shared options here with pgfplotsset:
\pgfplotsset{
height=6cm, width=9cm,
no markers
}
% this is the leftmost y axis (y2)
\begin{axis}[
xmin=0,xmax=1,%--- CF
xshift=-2.0cm,%-- CF
width=2cm,
hide x axis,
axis y line*=left,
ymin=0, ymax=10,
ytick = {0,1,...,10},
ylabel={\color{red}$y_2$}
]
\end{axis}
% this is the inner y axis (y1)
\begin{axis}[
xmin=0, xmax=10,
xshift=-0.3cm,%-- CF
width=2cm,
hide x axis,
axis y line*=left,
ymin=0, ymax=100,
ytick = {0,20,...,100},
ylabel={\color{blue}$y_1$}
]
\end{axis}
% this is the unique x-axis
\begin{axis}[
height=2cm, yshift=-0.4cm,
xmin=0, xmax=10,
ymin=0, ymax=100,
ytick = {0,1,...,10},
axis x line*=bottom,
hide y axis,
xlabel={$x$}
]
\end{axis}
% this is the blue curve
\begin{axis}[
xmin=0, xmax=10,
ymin=0, ymax=100,
hide x axis,
hide y axis,
]
\end{axis}
% this is the red curve
\begin{axis}[
xmin=0, xmax=10,
ymin=0, ymax=10,
hide x axis,
hide y axis,
]
\end{axis}
% this is the green curve
\begin{axis}[
xmin=0, xmax=10,
ymin=-5.5, ymax=5.5,
hide x axis,
hide y axis,
]
\end{axis}
% this is the right-hand y-axis (y3)
\pgfplotsset{every axis y label/.append style={rotate=180}}
\begin{axis}[
xmin=0, xmax=10,
ymin=-5.0, ymax=5.0,
xshift=0.3cm,%-- CF
hide x axis,
axis y line*=right,
ytick = {-5,-4,...,5},
ylabel={\color{green!50!black}$y_3$}
]
\end{axis}
\end{tikzpicture}
\end{document}


Explanation

The idea here is to show more plots in the same area in order to compare them. A typical situation occurs when the range of x-coordinates is the same for all curves, while those of the y-coordinates are very different.

The curves are brought in the same region by issuing more axis environments, one for each curve, all with the same xmin and xmax values (while ymin and ymax are set as needed). For all these environments one can set hide x axis and hide y axis. Then, each single y-axis, and the common x-axis, is drawn with a separate additional axis environment (with no \addplot command inside).

Comments in the above code mark the places where single axes are created:

• the left-most y-axis, i.e. the one with a red label (y2), shifted left of 2 cm,
• the inner y-axis, blue label (y1), shifted left of 0.3 cm,
• the unique x-axis, shifted down of 0.4 cm,
• the right-hand y-axis, green label (y3), shifted right of 0.3 cm.

These axis environments merely serve to draw the axis lines with their ticks. All other axis environments draw the curves.

-
Do you mind explaining the code and your changes to it? –  N.N. Nov 17 '11 at 20:43
I think the result would be more cohesive if the three axes y were on the same side of the figure without y1, y3 and y3 but with the color of each plot. Or with labels above axes ? –  Alain Matthes Apr 22 '12 at 12:04
@Altermundus Yes, putting labels above y-axes is a good idea. But with such a kind of graph the best arrangement really depends on the context and on how much space you have. –  agodemar May 4 '12 at 14:16