如何生成具有多个分组数据集的 xy 图?

如何生成具有多个分组数据集的 xy 图?

根据以下答案斯蒂芬·平诺“如何将多张图表分组为一张图表?”,我尝试生成一个包含多个分组数据的图表。因此,我修改了该图表,但遇到了一些问题。生成的图表现在如下所示:

在此处输入图片描述

这是我的 MWE(我希望它的 MWE 尽可能小):

% restructured data file:
% - 'n' values are sorted ascending
% - added column 'z' to know which data belong to which measurement
% - added a dummy line at the end of each data set to produce an empty entry
%   for the separation of the blocks
% - put all data in one file
\begin{filecontents}{data.txt}
z   n     val1  val2  val3
10  0.1   6    10      400.0
10  1.0   9    70      300.0
10  10.0 10   120      100.0
10  {}    {}   {}     {}
20  0.1   10   80      500.0
20  1.0   15   95    600.0
20  10.0 20   140      690.0
20  {}    {}   {}     {}
30  0.1  15   100      450.0
30  1.0  18   200      700.0
30  10.0 28   260     850.0
30  {}    {}   {}    {}
40  0.1  13   300      1500.0
40  1.0  19   260      1300.0
40  10.0 21   220    1000.0
40  {}    {}   {}     {}
50  0.1   25   250     3000.0
50  1.0   37   180   2400.0
50  10.0  34   100    2000.0
\end{filecontents}

\documentclass[border=0pt]{standalone}
\usepackage{pgfplots}
    \usetikzlibrary{patterns}
    \pgfplotsset{
       compat=newest,
       scale only axis,
       ymajorgrids=true,
       tick align = outside,
       yticklabel style={
         /pgf/number format/fixed zerofill,
         /pgf/number format/precision=1,
       },
       legend style={
         text=black,
         legend pos=north west,
         legend cell align={left},
       },  
    }    

\begin{document}
    \begin{tikzpicture}

    \begin{axis}[
        color=black,
        % set the `width' of the plot to the maximum length ...
        width=\textwidth,
        % ... and use half this length for the `height'
        height=0.5\textwidth,
        scale only axis,
        /pgf/number format/.cd,
        use comma,
        1000 sep={\,},
        ymin=-0.5,
        ymax=30.5,
        ytick={0.0, 5.0, ..., 30.0},
        % use `data' for the positioning of the `xticks' ...
        xtick=data,
        % ... and use table data for labeling the `xticks'
        xticklabels from table={data.txt}{n},
        % add extra ticks "at the empty entries to add the vertical lines
        extra x ticks={3,7,11,15},
        % this ticks shouldn't be labeled ...
        extra x tick labels={},
        % ... but grid lines should be drawn without the tick lines
        extra x tick style={
            grid=major,
            major tick length=0pt,
        },
        xlabel={X Axis 1 Label},
        ylabel={Y Axis 1 Label},
        ylabel style={blue},
        y axis line style={blue},
        ytick style={blue},
        yticklabel style=blue,
        xtick pos=bottom,
        axis y line*=left,
        % because of the category labels, shift the `xlabel' a bit down
        xlabel style={
            yshift=-4ex,
        },
        % ... and with that you also have to adjust the x limits
        enlarge x limits={abs=1},
        % set `clip mode' to `individual' so the category labels aren't clipped away
        clip mode=individual,
    ]

    % plot the "blue" points
        \addplot [
            color=blue,
            only marks,
            mark size=2pt,
            mark=square*,
            mark options={solid,fill=blue},
        ] table [
            % use just the `coordindex' as x coordinate,
            % the correct labeling is done with `xticklabels from table'
            x expr=\coordindex,
            y=val1,
        ] {data.txt};
        \label{label-plot1}

        % add the category labels
        \begin{scope}[
            % because the reference point will be the lower axis line the
            % labels have to be moved a bit more down to don't overlap with
            % the `xticklabels'
            every label/.append style={
                label distance=3ex,
            },
        ]
            \node [label=below:{System A}]
                at (axis cs:1,\pgfkeysvalueof{/pgfplots/ymin}) {};
            \node [label=below:{System B}]
                at (axis cs:5,\pgfkeysvalueof{/pgfplots/ymin}) {};
            \node [label=below:{System C}]
                at (axis cs:9,\pgfkeysvalueof{/pgfplots/ymin}) {};
            \node [label=below:{System D}]
                at (axis cs:13,\pgfkeysvalueof{/pgfplots/ymin}) {};
            \node [label=below:{System E}]
                at (axis cs:17,\pgfkeysvalueof{/pgfplots/ymin}) {};
        \end{scope}

    \end{axis}



    % Frame 2
    \begin{axis}[
        color = red,
        % set the `width' of the plot to the maximum length ...
        width=\textwidth,
        % ... and use half this length for the `height'
        height=0.5\textwidth,
        scale only axis,            
        /pgf/number format/.cd,
        use comma,
        1000 sep={\,},
        ymin=-5.0,
        ymax=305.0,
        ytick={0.0, 50.0, ..., 300.0},
        % use `data' for the positioning of the `xticks' ...
        xtick=data,
      % ... and use table data for labeling the `xticks'
        xticklabels from table={data.txt}{n},
        % add extra ticks "at the empty entries to add the vertical lines
        extra x ticks={3,7,11,15},
        % this ticks shouldn't be labeled ...
        extra x tick labels={},
        % ... but grid lines should be drawn without the tick lines
        extra x tick style={
            grid=major,
            major tick length=0pt,
        },
        ylabel={Y Axis 2 Label},
        % because of the category labels, shift the `xlabel' a bit down
        xlabel style={
            yshift=-4ex,
        },
        ytick style={red},
        axis x line*=none,
        axis y line*=right,            
        ylabel style = red,
        % ... and with that you also have to adjust the x limits
        enlarge x limits={abs=1},
        % set `clip mode' to `individual' so the category labels aren't clipped away
        clip mode=individual,           
        hide x axis            
    ]

    % plot the "red" points
        \addplot [
            color=red,
            only marks,
            mark size=2pt,
            mark=triangle*,
            mark options={solid,fill=red}         
        ] table [
            x expr=\coordindex,
            y=val2,
        ] {data.txt};
        \label{label-plot2}

    \end{axis}


    % Frame 3
    \begin{axis}[
        color = green,
        % set the `width' of the plot to the maximum length ...
        width=\textwidth,
        % ... and use half this length for the `height'
        height=0.5\textwidth,           
        scale only axis,
        /pgf/number format/.cd,
        use comma,
        1000 sep={\,},
        ymin=-50,
        ymax=3050.,
        ytick={0, 500, ..., 3000},            
        % use `data' for the positioning of the `xticks' ...
        xtick=data,
      % ... and use table data for labeling the `xticks'
        xticklabels from table={data.txt}{n},
        % add extra ticks "at the empty entries to add the vertical lines
        extra x ticks={3,7,11,15},
        % this ticks shouldn't be labeled ...
        extra x tick labels={},
        % ... but grid lines should be drawn without the tick lines
        extra x tick style={
            grid=major,
            major tick length=0pt,
        },
        ylabel={Y Axis 3 Label},
        % because of the category labels, shift the `xlabel' a bit down
        xlabel style={
            yshift=-4ex,
        },
        ylabel style = green,            
        ytick style={green},
        axis x line*=none,
        axis y line*=right,            
        % ... and with that you also have to adjust the x limits
        enlarge x limits={abs=1},
        % set `clip mode' to `individual' so the category labels aren't clipped away
        clip mode=individual,           
        hide x axis,
        every outer y axis line/.style={
           green,
           xshift=2.0cm
        },
        every tick/.style={
          green,
          xshift=2.0cm
        },
        every y tick label/.append style={
          green,
          xshift=2.0cm
        },          
    ]

      % plot the legend
       \addlegendimage{refstyle=label-plot1} \addlegendentry{ \color{blue}{Algorithm A}}
       \addlegendimage{refstyle=label-plot2} \addlegendentry{ \color{red}{Algorithm B} }
       \addlegendimage{refstyle=label-plot3} \addlegendentry{ \color{green}{Algorithm C} }


       % plot the "green" points
        \addplot [
            color=green,
            only marks,
            mark size=2pt,
            mark=diamond*,
            mark options={solid,fill=green},
        ] table [
            x expr=\coordindex,
            y=val3,
        ] {data.txt};
        \label{label-plot3}

    \end{axis}

    \end{tikzpicture}
\end{document}  

我的问题/疑问是:

  1. 系统 E 的最后一个数据集未完全可视化。我该如何解决这个问题?
  2. x 轴上的数据点排列有些错误。我做错了什么?
  3. “算法 B”和“算法 C”的数据点与“算法 A”和 x 轴的相关性存在一些错位。您有什么提示可以解决这个问题吗?
  4. 我还想将多行文本写为列标题,并定义换行符。与“系统 A”相反,应该是“系统 A \n \n 参数:\n \alpha=5 \n beta=3 \n \lambda=8”。使用换行符 (\n) 不起作用。您能给我一点提示吗?
  5. 是否可以在一个组(此处按颜色分组:“算法 A”)内的另一个分组(此处:按系统分组,例如“系统 A”)的点(此处:0.1、1.0、10.0)之间绘制互连线(例如:虚线),但不能在组之间(此处:系统之间)绘制互连线?

答案1

我认为主要问题是您ymax=30.5在第一个轴中有axis,而数据的最大值为 37。因此,并非所有点都已绘制。我也需要在第一个轴中更改xtick=data为,但不知道为什么。xtick={0,...,18}

我还改变了所有三个轴的 ylimits 和 yticks。

对于 System N 节点,我认为不使用label而是直接使用节点内容并添加align=center到节点选项会更容易。(我在这里使用 样式every node,类似于every label原来的样式。)align=center您可以使用\\在节点中添加换行符。

对于连接线,将{}数据文件中的 替换为inf,添加unbounded coords=jump\pgfplotsset,并将only marks中的替换\addplotdotted

在此处输入图片描述

% restructured data file:
% - 'n' values are sorted ascending
% - added column 'z' to know which data belong to which measurement
% - added a dummy line at the end of each data set to produce an empty entry
%   for the separation of the blocks
% - put all data in one file
\begin{filecontents}{data.txt}
z   n     val1  val2  val3
10  0.1   6    10      400.0
10  1.0   9    70      300.0
10  10.0 10   120      100.0
10  inf    inf   inf     inf
20  0.1   10   80      500.0
20  1.0   15   95    600.0
20  10.0 20   140      690.0
20  inf    inf   inf     inf
30  0.1  15   100      450.0
30  1.0  18   200      700.0
30  10.0 28   260     850.0
30  inf    inf   inf    inf
40  0.1  13   300      1500.0
40  1.0  19   260      1300.0
40  10.0 21   220    1000.0
40  inf    inf   inf     inf
50  0.1   25   250     3000.0
50  1.0   37   180   2400.0
50  10.0  34   100    2000.0
\end{filecontents}

\documentclass[border=0pt]{standalone}
\usepackage{pgfplots}
    \usetikzlibrary{patterns}
    \pgfplotsset{
       compat=newest,
       scale only axis,
       ymajorgrids=true,
       tick align = outside,
       yticklabel style={
         /pgf/number format/fixed zerofill,
         /pgf/number format/precision=1,
       },
       legend style={
         text=black,
         legend pos=north west,
         legend cell align={left},
       },
       unbounded coords=jump  
    }    

\begin{document}
    \begin{tikzpicture}

    \begin{axis}[
        color=black,
        % set the `width' of the plot to the maximum length ...
        width=\textwidth,
        % ... and use half this length for the `height'
        height=0.5\textwidth,
        scale only axis,
        /pgf/number format/.cd,
        use comma,
        1000 sep={\,},
        ymin=-0.5,
        ymax=37.5,
        ytick={0.0, 5.0, ..., 35.0},
        % use 0,...,18
        xtick={0,...,18},
        % ... and use table data for labeling the `xticks'
        xticklabels from table={data.txt}{n},
        % add extra ticks "at the empty entries to add the vertical lines
        extra x ticks={3,7,11,15},
        % this ticks shouldn't be labeled ...
        extra x tick labels={},
        % ... but grid lines should be drawn without the tick lines
        extra x tick style={
            grid=major,
            major tick length=0pt,
        },
        xlabel={X Axis 1 Label},
        ylabel={Y Axis 1 Label},
        ylabel style={blue},
        y axis line style={blue},
        ytick style={blue},
        yticklabel style=blue,
        xtick pos=bottom,
        axis y line*=left,
        % because of the category labels, shift the `xlabel' a bit down
        xlabel style={
            yshift=-4ex,
        },
        % ... and with that you also have to adjust the x limits
        enlarge x limits={abs=1},
        % set `clip mode' to `individual' so the category labels aren't clipped away
        clip mode=individual,
    ]

    % plot the "blue" points
        \addplot [
            color=blue,
            dotted,
            mark size=2pt,
            mark=square*,
            mark options={solid,fill=blue},
        ] table [
            % use just the `coordindex' as x coordinate,
            % the correct labeling is done with `xticklabels from table'
            x expr=\coordindex,
            y=val1,
        ] {data.txt};
        \label{label-plot1}

        % add the category labels
        \begin{scope}[
            % because the reference point will be the lower axis line the
            % nodes have to be moved a bit more down to don't overlap with
            % the `xticklabels'
            every node/.append style={
                below=3.2ex,align=center,
            },
        ]
            \node at (axis cs:1,\pgfkeysvalueof{/pgfplots/ymin}) {System A\\foo};
            \node at (axis cs:5,\pgfkeysvalueof{/pgfplots/ymin}) {System B\\foo};
            \node at (axis cs:9,\pgfkeysvalueof{/pgfplots/ymin}) {System C\\foo};
            \node at (axis cs:13,\pgfkeysvalueof{/pgfplots/ymin}) {System D\\foo};
            \node at (axis cs:17,\pgfkeysvalueof{/pgfplots/ymin}) {System E\\foo};
        \end{scope}

    \end{axis}



    % Frame 2
    \begin{axis}[
        color = red,
        % set the `width' of the plot to the maximum length ...
        width=\textwidth,
        % ... and use half this length for the `height'
        height=0.5\textwidth,
        scale only axis,            
        /pgf/number format/.cd,
        use comma,
        1000 sep={\,},
        ymin=-5.0,
        ymax=375.0,
        ytick={0.0, 50.0, ..., 350.0},
        % use `data' for the positioning of the `xticks' ...
        xtick=data,
      % ... and use table data for labeling the `xticks'
        xticklabels from table={data.txt}{n},
        % add extra ticks "at the empty entries to add the vertical lines
        extra x ticks={3,7,11,15},
        % this ticks shouldn't be labeled ...
        extra x tick labels={},
        % ... but grid lines should be drawn without the tick lines
        extra x tick style={
            grid=major,
            major tick length=0pt,
        },
        ylabel={Y Axis 2 Label},
        % because of the category labels, shift the `xlabel' a bit down
        xlabel style={
            yshift=-4ex,
        },
        ytick style={red},
        axis x line*=none,
        axis y line*=right,            
        ylabel style = red,
        % ... and with that you also have to adjust the x limits
        enlarge x limits={abs=1},
        % set `clip mode' to `individual' so the category labels aren't clipped away
        clip mode=individual,           
        hide x axis            
    ]

    % plot the "red" points
        \addplot [
            color=red,
            dotted,
            mark size=2pt,
            mark=triangle*,
            mark options={solid,fill=red}         
        ] table [
            x expr=\coordindex,
            y=val2,
        ] {data.txt};
        \label{label-plot2}

    \end{axis}


    % Frame 3
    \begin{axis}[
        color = green,
        % set the `width' of the plot to the maximum length ...
        width=\textwidth,
        % ... and use half this length for the `height'
        height=0.5\textwidth,           
        scale only axis,
        /pgf/number format/.cd,
        use comma,
        1000 sep={\,},
        ymin=-50,
        ymax=3750.,
        ytick={0, 500, ..., 3500},            
        % use `data' for the positioning of the `xticks' ...
        xtick=data,
      % ... and use table data for labeling the `xticks'
        xticklabels from table={data.txt}{n},
        % add extra ticks "at the empty entries to add the vertical lines
        extra x ticks={3,7,11,15},
        % this ticks shouldn't be labeled ...
        extra x tick labels={},
        % ... but grid lines should be drawn without the tick lines
        extra x tick style={
            grid=major,
            major tick length=0pt,
        },
        ylabel={Y Axis 3 Label},
        % because of the category labels, shift the `xlabel' a bit down
        xlabel style={
            yshift=-4ex,
        },
        ylabel style = green,            
        ytick style={green},
        axis x line*=none,
        axis y line*=right,            
        % ... and with that you also have to adjust the x limits
        enlarge x limits={abs=1},
        % set `clip mode' to `individual' so the category labels aren't clipped away
        clip mode=individual,           
        hide x axis,
        every outer y axis line/.style={
           green,
           xshift=2.0cm
        },
        every tick/.style={
          green,
          xshift=2.0cm
        },
        every y tick label/.append style={
          green,
          xshift=2.0cm
        },          
    ]

      % plot the legend
       \addlegendimage{refstyle=label-plot1} \addlegendentry{ \color{blue}{Algorithm A}}
       \addlegendimage{refstyle=label-plot2} \addlegendentry{ \color{red}{Algorithm B} }
       \addlegendimage{refstyle=label-plot3} \addlegendentry{ \color{green}{Algorithm C} }


       % plot the "green" points
        \addplot [
            color=green,
            dotted,
            mark size=2pt,
            mark=diamond*,
            mark options={solid,fill=green},
        ] table [
            x expr=\coordindex,
            y=val3,
        ] {data.txt};
        \label{label-plot3}

    \end{axis}

    \end{tikzpicture}
\end{document}  

相关内容