pgfplots:如何将绘图宽度与图例宽度对齐?

pgfplots:如何将绘图宽度与图例宽度对齐?

用户土拨鼠发布了一个很好的方法,将图例放在多重图表下方。


最小工作示例(MWE):

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{positioning}
\pgfplotsset{compat=newest, scale only axis}
\begin{document}
\pgfplotsset{superb legend/.style={legend style                                = {draw=none,
                 legend columns                          = 3,
                 /tikz/every even column/.append style   = {column sep=0.5cm,
                 text width=7em},
                 /tikz/every odd column/.append style    = {column sep=0.15cm,
                  text width=7em},
                 }}}
\begin{tikzpicture}
\begin{scope}[local bounding box=plots]
 \begin{axis}[
             axis y line*                                = left,
             legend to name                              = legA,
             superb legend
             ]%
             \addplot coordinates {(0,0) (1,1)};
             \addplot coordinates {(1,0) (0,1)};
             \addplot coordinates {(0,1) (1,1)};
             \legend{Graph 1, Graph 2, Graph 3};
 \end{axis}%
 %
 \begin{axis}[
             axis x line                                 = none,
             axis y line*                                = right,
             legend to name                              = legB,
             superb legend
             ]%
             \addplot coordinates {(0,1) (1,0)};
             \addplot coordinates {(0,0.5) (1,0.5)};
             \addplot coordinates {(0,0.15) (1,0.15)};
             \legend{Graphinggraph~4, Graphinggraph~5, Graphinggraph~6};
 \end{axis}%
 %
 \begin{axis}[
             axis x line                                 = none,
             axis y line*                                = right,
             legend to name                              = legC,
             superb legend
             ]%
             \pgfplotsset%
                 {%
                 every outer y axis line/.style          = {xshift=2cm},
                 every tick/.style                       = {xshift=2cm},
                 every y tick label/.style               = {xshift=2cm},
                 }%
             \addplot coordinates {(0.5,0) (0.5,1)};
             \addplot coordinates {(0.6,0) (0.6,1)};
             \addplot coordinates {(0.7,0) (0.7,1)};
             \legend{Graphgraph 7, Graphgraph 8, Graphgraph 9};
 \end{axis}%
\end{scope}
\node[below=3.5em of plots.south] (legA) {\ref{legA}};
\node[below=-0.5em of legA] (legB) {\ref{legB}};
\node[below=-0.5em of legB] (legC) {\ref{legC}};
\draw (legA.north west) rectangle (legC.south east);
\end{tikzpicture}
\end{document}

结果截图:

结果截图


问题说明:

  • 是否可以将绘图的宽度调整为图例框的宽度(参见上面带有红色标记的屏幕截图)?

或者反过来:

  • 将图例框的宽度调整为图表的宽度?

如何在不摆弄图例项的情况下完美地解决这个问题text width?也许我们可以创建一些全局变量来一起指定图例和绘图的宽度?

答案1

这有点像“先有鸡还是先有蛋”的问题,因为我们只能在绘制完图例后才能构建图例,但绘制图例时应该根据图例的大小进行调整。这可以在 LaTeX 中解决是将宽度写入辅助文件,下次编译时将从那里读取并使用它。这也用于奇妙的库中tikzmark,更普遍地用于保存和使用坐标时remember picture。是的,这意味着您需要编译多次(这里至少需要编译三次,因为在第一次运行中图例只是问号),但如果您愿意这样做,这似乎可行。

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{positioning,calc}
\pgfplotsset{compat=newest, scale only axis}
\begin{document}
\pgfplotsset{superb legend/.style={legend style                                = {draw=none,
                 legend columns                          = 3,
                 /tikz/every even column/.append style   = {column sep=0.5cm,
                 text width=7em},
                 /tikz/every odd column/.append style    = {column sep=0.15cm,
                  text width=7em},
                 }}}
\begin{tikzpicture}
\ifdefined\mylegendwidth
\ifdim\mylegendwidth<0pt
\pgfmathsetmacro{\mywidth}{abs(\mylegendwidth)}
\def\mylegendwidth{\mywidth pt}
\fi
\else
\typeout{Please\space recompile\space your\space file!}
\def\mylegendwidth{10cm}
\fi
\pgfplotsset{width=\mylegendwidth}
\begin{scope}[local bounding box=plots]
 \begin{axis}[
             axis y line*                                = left,
             legend to name                              = legA,
             superb legend
             ]%
             \addplot coordinates {(0,0) (1,1)};
             \addplot coordinates {(1,0) (0,1)};
             \addplot coordinates {(0,1) (1,1)};
             \legend{Graph 1, Graph 2, Graph 3};
 \end{axis}%
 %
 \begin{axis}[
             axis x line                                 = none,
             axis y line*                                = right,
             legend to name                              = legB,
             superb legend
             ]%
             \addplot coordinates {(0,1) (1,0)};
             \addplot coordinates {(0,0.5) (1,0.5)};
             \addplot coordinates {(0,0.15) (1,0.15)};
             \legend{Graphinggraph~4, Graphinggraph~5, Graphinggraph~6};
 \end{axis}%
 %
 \begin{axis}[
             axis x line                                 = none,
             axis y line*                                = right,
             legend to name                              = legC,
             superb legend
             ]%
             \pgfplotsset%
                 {%
                 every outer y axis line/.style          = {xshift=2cm},
                 every tick/.style                       = {xshift=2cm},
                 every y tick label/.style               = {xshift=2cm},
                 }%
             \addplot coordinates {(0.5,0) (0.5,1)};
             \addplot coordinates {(0.6,0) (0.6,1)};
             \addplot coordinates {(0.7,0) (0.7,1)};
             \legend{Graphgraph 7, Graphgraph 8, Graphgraph 9};
 \path (current axis.west) coordinate (aux1)  ([xshift=2cm]current axis.east)
  coordinate (aux2);
 \end{axis}%
\end{scope}
\node[anchor=north west] at ([yshift=-3.5em]plots.south-|aux1) (legA) {\ref{legA}};
\node[below=-0.5em of legA] (legB) {\ref{legB}};
\node[below=-0.5em of legB] (legC) {\ref{legC}};
\draw let \p1=($(legC.east)-(legA.west)$),\p2=($(aux2)-(aux1)$) in
[/utils/exec=\pgfmathsetmacro{\mywidth}{\mylegendwidth+\x1-\x2}%
\xdef\mylegendwidth{\mywidth pt}]
 (legA.north west) rectangle (legC.south east);
\makeatletter
 \immediate\write\@mainaux{\xdef\string\mylegendwidth{\mylegendwidth}\relax}
\makeatother
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

只需缩放轴以匹配图例大小即可。如下所示:

\pgfplotsset{scale=1.12}

虽然不是一个优雅的解决方案,但它确实有效。;)

在此处输入图片描述

代码:

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{positioning}
\pgfplotsset{compat=newest, scale only axis,scale=1.12}
\pgfplotsset{scale=1.12}

\begin{document}
\pgfplotsset{superb legend/.style={     legend style                                = {draw=none,
                 legend columns                          = 3,
                 /tikz/every even column/.append style   = {column sep=0.5cm,
                 text width=7em},
                 /tikz/every odd column/.append style    = {column sep=0.15cm,
                  text width=7em},
                 }}}
\begin{tikzpicture}
\begin{scope}[local bounding box=plots]
 \begin{axis}[
             axis y line*                                = left,
             legend to name                              = legA,
             superb legend
             ]%
             \addplot coordinates {(0,0) (1,1)};
             \addplot coordinates {(1,0) (0,1)};
             \addplot coordinates {(0,1) (1,1)};
             \legend{Graph 1, Graph 2, Graph 3};
 \end{axis}%
 %
 \begin{axis}[
             axis x line                                 = none,
             axis y line*                                = right,
             legend to name                              = legB,
             superb legend
             ]%
             \addplot coordinates {(0,1) (1,0)};
             \addplot coordinates {(0,0.5) (1,0.5)};
             \addplot coordinates {(0,0.15) (1,0.15)};
             \legend{Graphinggraph~4, Graphinggraph~5, Graphinggraph~6};
 \end{axis}%
 %
 \begin{axis}[
             axis x line                                 = none,
             axis y line*                                = right,
             legend to name                              = legC,
             superb legend
             ]%
             \pgfplotsset%
                 {%
                 every outer y axis line/.style          = {xshift=2cm},
                 every tick/.style                       = {xshift=2cm},
                 every y tick label/.style               = {xshift=2cm},
                 }%
             \addplot coordinates {(0.5,0) (0.5,1)};
             \addplot coordinates {(0.6,0) (0.6,1)};
             \addplot coordinates {(0.7,0) (0.7,1)};
             \legend{Graphgraph 7, Graphgraph 8, Graphgraph 9};
 \end{axis}%
\end{scope}
\node[below=3.5em of plots.south] (legA) {\ref{legA}};
\node[below=-0.5em of legA] (legB) {\ref{legB}};
\node[below=-0.5em of legB] (legC) {\ref{legC}};
\draw (legA.north west) rectangle (legC.south east);
\end{tikzpicture}
\end{document}

相关内容