尝试连接箱线图中的坐标

尝试连接箱线图中的坐标

我是新来的,所以如果我没有遵守规则,请告诉我。我不是 pgfplots 的常客。

我正在尝试使用 pgfplots 和 tikzpicture 连接箱线图中的坐标。数据是成对的,每个点都应该连接到其对应点,因为它们是同一患者的数据。在这里您可以看到我的结果。在此处输入图片描述我不明白为什么这些点没有连接。我找到了这些点的坐标并将它们放在一个数组中。最后,我用画线将这些点连接起来。有谁知道为什么有些点看起来是连接的,而另一些点看起来是不连贯的?如果有人问我为什么要使用箱线图,我的主管明确要求我使用箱线图,尽管数据确实要求这样做。这张图片大致说明了我在箱线图中试图实现的目标:

在此处输入图片描述

\documentclass[a4paper,12pt,twoside]{book}
\usepackage{filecontents} 
\usepackage{graphicx, tabularx}
\usepackage{pgfplotstable}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepgfplotslibrary{statistics}
\usepackage{xcolor}
\begin{filecontents*}{data.csv}
b-SSFP_RA   b-SSFP_SA   CE_MRA_SA   CE_MRA_SA
246,78      288,75      254,99      307,63
283,38      183,85      283,56      60,35
158,01      205,85      170,87      88,10
114,81      322,72      107,00      28,42
161,04      169,25      129,56      69,58
\end{filecontents*}
\pgfplotstablegetrowsof{data.csv}
\pgfmathtruncatemacro{\N}{\pgfplotsretval-1}
\pgfplotsset{
  tick label style = {font=\sansmath\sffamily},
  every axis label = {font=\sansmath\sffamily},
  legend style = {font=\sansmath\sffamily},
  label style = {font=\sansmath\sffamily}}

\begin{document}

\begin{figure}
\centering
\begin{tikzpicture}
\begin{axis}[width = 0.9\textwidth,
boxplot/draw direction=y,
ylabel={CNR},
height=7cm,
very thick,
legend style={nodes=right,very thick},
boxplot={
draw position={1/5 + floor(\plotnumofactualtype/2) + 1/2*mod(\plotnumofactualtype,2)},
box extend=0.3},
ymajorgrids,
x=4cm,
xtick={0,1,2,...,10},
xticklabels={Renal artery,Segmental artery},%
x tick label as interval,
x tick label style={
text width=3.5cm,
align=center},
xlabel=Anatomic region,
legend entries = {b-SSFP, CE-MRA},
legend to name={legend},
name=border]


\addplot+ [blue,  opacity=1,fill=blue!30,fill opacity=0.3, very thick][row sep=\\,
     boxplot prepared={
     lower whisker=114.82,
     lower quartile=158.01,
     median=161.41,
     upper quartile=246.78,
     upper whisker=283.39,}
     ] coordinates {(0,247)(0,284)(0,158)(0,115)(0,161)}
     \foreach \i in {1,...,\N} {
                coordinate [pos=\i/\N] (a\i)
            };
\addplot+ [orange,  opacity=1,fill=orange!30,fill opacity=0.3, very thick][row sep=\\,
     boxplot prepared={
     lower whisker=169.26,
     lower quartile=183.85,
     median=205.85,
     upper quartile=288.75,
     upper whisker=322.72,}
     ] coordinates {(0,289)(0,184)(0,206)(0,323)(0,169)}
     \foreach \i in {1,...,\N} {
                coordinate [pos=\i/\N] (b\i)
            };
\addplot+ [blue,  opacity=1,fill=blue!30,fill opacity=0.3, very thick][row sep=\\,
    boxplot prepared={
     lower whisker=107.00,
     lower quartile=129.56,
     median=170.87,
     upper quartile=254.99,
     upper whisker=283.57,}
     ] coordinates {(0,255)(0,284)(0,171)(0,107)(0,130)}
          \foreach \i in {1,...,\N} {
                coordinate [pos=\i/\N] (c\i)
            };
\addplot+ [orange,  opacity=1,fill=orange!30,fill opacity=0.3, very thick][row sep=\\,
     boxplot prepared={
     lower whisker=28.42,
     lower quartile=60.35,
     median=69.58,
     upper quartile=88.10,
     upper whisker=307.63}
     ]  coordinates {(0,308)(0,60)(0,88)(0,28)(0,70)}
          \foreach \i in {1,...,\N} {
                coordinate [pos=\i/\N] (d\i)
            };
\end{axis}
 \foreach \i in {1,...,\N} {\draw (a\i) -- (b\i);
        };
 \foreach \i in {1,...,\N} {\draw (c\i) -- (d\i);
};
\node[below right] at (border.north east) {\ref{legend}};
\end{tikzpicture}
\end{figure}
\end{document}

答案1

原则上,您添加连接线的想法是正确的,但不起作用,因为异常值是在一条不可见的线上绘制的,因此pos计算是根据这条线而不是“点的索引”进行的。有关详细信息,请参阅PGFPlots 手册(v1.16)第 356 页第 4.17.2 节

为了避免这个问题,你可以将“异常值”移至其他\addplot命令。有关详细信息,请查看代码中的注释。

% used PGFPlots v1.16
% changes to the data file
% - replaced commata by points
% - corrected/changed "SA" to "RA" in second last column (to avoid duplicate name)
\begin{filecontents*}{data.csv}
b-SSFP_RA   b-SSFP_SA   CE_MRA_RA   CE_MRA_SA
246.78      288.75      254.99      307.63
283.38      183.85      283.56      60.35
158.01      205.85      170.87      88.10
114.81      322.72      107.00      28.42
161.04      169.25      129.56      69.58
\end{filecontents*}
\documentclass[border=5pt]{standalone}
\usepackage{pgfplotstable}
    \usepgfplotslibrary{statistics}
    \pgfplotsset{
        compat=1.3,
        % create a style for the box plots
        % (which takes an argument for the color)
        box style/.style={
            #1,
            solid,
            fill=#1!30,
            fill opacity=0.3,
            boxplot={
                draw position={1/5 + floor(\plotnumofactualtype/2) + 1/2*mod(\plotnumofactualtype,2)},
                box extend=0.3,
            },
        },
        % create a style for the marks
        % (which also takes an argument for the color)
        mark style/.style={
            #1,
            mark=*,
            only marks,
            table/x expr={1/5 + floor(\plotnumofactualtype/2) + 1/2*mod(\plotnumofactualtype,2)},
        },
    }
    \pgfplotstablegetrowsof{data.csv}
    \pgfmathtruncatemacro{\N}{\pgfplotsretval-1}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        width=0.9\textwidth,
        height=7cm,
        xlabel=Anatomic region,
        ylabel={CNR},
        xtick={0,...,3},
        xticklabels={Renal artery,Segmental artery},
        x tick label as interval,
        x tick label style={
            text width=3.5cm,
            align=center,
        },
        very thick,
        ymajorgrids,
        boxplot/draw direction=y,
        legend pos=outer north east,
        % because you (most likely) only want to plot the dots you need to
        % skip the boxplots, which can be done by giving an empty entry
        % (this is why the entries start with a comma)
        legend entries={
            ,b-SSFP,
            ,CE-MRA
        },
    ]
        \addplot+ [
            % use the created style here
            box style=blue,
            boxplot prepared={
                lower whisker=114.82,
                lower quartile=158.01,
                median=161.41,
                upper quartile=246.78,
                upper whisker=283.39,
            },
        % remove the marks from here ...
        ] coordinates {};
        % ... and add them as extra `\addplot`s ...
        \addplot [
            mark style=blue,
        ] table [
            y=b-SSFP_RA,
        ] {data.csv}
            % ... including the `\foreach` part giving coordinate names to
            % the points
            % (Please note that the index starts at 0 and not 1.)
            \foreach \i in {0,...,\N} {
                coordinate [pos=\i/\N] (a\i)
            }
        ;

        \addplot+ [
            box style=orange,
            boxplot prepared={
                lower whisker=169.26,
                lower quartile=183.85,
                median=205.85,
                upper quartile=288.75,
                upper whisker=322.72,
            },
        ] coordinates {};
        \addplot [
            mark style=orange,
        ] table [
            y=b-SSFP_SA,
        ] {data.csv}
            \foreach \i in {0,...,\N} {
                coordinate [pos=\i/\N] (b\i)
            }
        ;

        \addplot+ [
            box style=blue,
            boxplot prepared={
                lower whisker=107.00,
                lower quartile=129.56,
                median=170.87,
                upper quartile=254.99,
                upper whisker=283.57,
            },
        ] coordinates {};
        \addplot [mark style=blue] table [
            y=CE_MRA_RA,
        ] {data.csv}
            \foreach \i in {0,...,\N} {
                coordinate [pos=\i/\N] (c\i)
        };

        \addplot+ [
            box style=orange,
            boxplot prepared={
                lower whisker=28.42,
                lower quartile=60.35,
                median=69.58,
                upper quartile=88.10,
                upper whisker=307.63,
            },
        ] coordinates {};
        \addplot [mark style=orange] table [
            y=CE_MRA_SA,
        ] {data.csv}
            \foreach \i in {0,...,\N} {
                coordinate [pos=\i/\N] (d\i)
            }
        ;
    \end{axis}

    % draw the connecting lines
    \foreach \i in {0,...,\N} {
        \draw (a\i) -- (b\i);
        \draw (c\i) -- (d\i);
    }
\end{tikzpicture}
\end{document}

该图显示了上述代码的结果

相关内容