4

I have a PGFplots set of grouped plots that somewhat resembles the following MWE. The top row of plots has a larger range than the bottom row. Is there a way to have the height of the top row automatically calculated such that the vertical scales - plot coordinates per pixel - on both rows are the same?

For the following example, the range of the top row is -5 to 15 (let me ignore enlarge limits for this), and the range of the bottom row is -5 to 5. So I would like the top row to be twice as high as the bottom row, but I don't want to have to code it explicitly. If I were to change the limits of the top row to (-5,10), then the height of the top row should automatically become 1.5 times that of the bottom row. If I change the limits of the top row to (-5,0), the height of the top row should automatically become 0.5 times that of the bottom row.

\documentclass{article}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.10}
\begin{document}
 \begin{tikzpicture}
  \begin{groupplot}[
    width=0.5\textwidth,
    group style={
     group size=2 by 2,
     x descriptions at=edge bottom,y descriptions at=edge left,
     horizontal sep=0pt,vertical sep=0pt
   }
  ]
  \nextgroupplot
   \addplot {2*x+5};
  \nextgroupplot
   \addplot {2*x+5};
  \nextgroupplot
   \addplot {x};
  \nextgroupplot
   \addplot {x};
  \end{groupplot}
 \end{tikzpicture}
\end{document}

Here is the result of compiling the example above as it is:

current result

and here is what I would like it to look like (or something like this):

desired result

The fact that the ticks go every 2 units in the second image, not every 5, is somewhat undesirable, but I can deal with that.

Some other factors to consider, which I think are irrelevant (and thus I kept them out of the MWE): in the real situation, the plot has a logarithmic scale on the y axis, and also the axis limits (xmin, ymin, etc.) are explicitly specified.

David Z
  • 12,084
  • 7
  • 48
  • 65

2 Answers2

2

You can use y post scale. Though a manual method as you have to specify the value, it produces the exact plot you want.

\documentclass{article}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.10}
\begin{document}
 \begin{tikzpicture}
  \begin{groupplot}[
    width=0.5\textwidth,
    group style={
     group size=2 by 2,
     x descriptions at=edge bottom,y descriptions at=edge left,
     horizontal sep=0pt,vertical sep=0pt
   }
  ]
  \nextgroupplot[y post scale=3]
   \addplot {2*x+5};
  \nextgroupplot[y post scale=3]
   \addplot {2*x+5};
  \nextgroupplot
   \addplot {x};
  \nextgroupplot
   \addplot {x};
  \end{groupplot}
 \end{tikzpicture}
\end{document}

enter image description here

With y post scale=2 we get

enter image description here

1

I stole the y post scale approach from Kumar, but added the code needed to compute the scale from the data.

group plot

\documentclass{article}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.10}

\newsavebox{\tempbox}
\newlength{\topscl}
\newlength{\bottomscl}

\newcommand{\computescale}[4]% #1 = macro to store answer, #2 = width used (or \axisdefaultwidth),
% #3 = \addplots for top row, #4 = \addplots for bottom row
{\savebox{\tempbox}{% get y scale for top row
\begin{tikzpicture}
\begin{axis}[width=#2,xtick=\empty]
 #3
 \coordinate (A) at (axis cs:0,0);
 \coordinate (B) at (axis cs:0,1);
\end{axis};
\pgfextracty{\topscl}{\pgfpointdiff{\pgfpointanchor{A}{center}}{\pgfpointanchor{B}{center}}}
\global\topscl=\topscl
\end{tikzpicture}}
\savebox{\tempbox}{% get y scale for bottom row
\begin{tikzpicture}
\begin{axis}[width=#2]
 #4
 \coordinate (A) at (axis cs:0,0);
 \coordinate (B) at (axis cs:0,1);
\end{axis};
\pgfextracty{\bottomscl}{\pgfpointdiff{\pgfpointanchor{A}{center}}{\pgfpointanchor{B}{center}}}
\global\bottomscl=\bottomscl
\end{tikzpicture}}
\pgfmathparse{\bottomscl/\topscl}%
\let#1=\pgfmathresult}

\begin{document}

\computescale{\scale}{0.5\textwidth}{\addplot {2*x+5};}{\addplot {x};}
scale = \scale

 \begin{tikzpicture}
  \begin{groupplot}[
    width=0.5\textwidth,
    group style={
     group size=2 by 2,
     x descriptions at=edge bottom,y descriptions at=edge left,
     horizontal sep=0pt,vertical sep=0pt    
   }
  ]
  \nextgroupplot[y post scale=\scale]
   \addplot {2*x+5};
  \nextgroupplot[y post scale=\scale]
   \addplot {2*x+5};
  \nextgroupplot
   \addplot {x};
  \nextgroupplot
   \addplot {x};
  \end{groupplot}
 \end{tikzpicture}
\end{document}
John Kormylo
  • 79,712
  • 3
  • 50
  • 120