当我想要绘制数据图时,我遇到了一个小问题。基本上,我正在处理 10 个不同的对象,它们具有多个属性。所以我有一个 csv 文件,有 10 行和许多列代表每个对象属性。每行都有一些“空白”,这意味着我们不知道这个对象的属性值。这在以下 MWE 中由 4 个对象 A、B、C 和 D 表示,它们具有属性 x、y、z。我们知道 A 和 D 的 x、y 和 z,只知道 B 的 x 和 z,以及 C 的 x 和 y。
\begin{filecontents*}{data.csv}
Label,x,y,z
A,1,5,9
B,4,,7
C,6,5,
D,7,3,4
\end{filecontents*}
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{csvsimple}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfplotsset{plot coordinates/math parser=false}
\usepgfplotslibrary{groupplots}
\begin{document}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\edef\tempa{\thisrow{#1}}
\edef\tempb{#2}
\ifx\tempa\tempb
\else
\def\pgfmathresult{inf}
\fi
}
}
}
\tikzset{every mark/.append style={scale=3}}
\pgfplotscreateplotcyclelist{mycolorlist}{%
mark=10-pointed star,only marks,point meta=explicit symbolic,blue,every mark/.append style={fill=blue!80!black}\\%
mark=diamond*,only marks,point meta=explicit symbolic,red,every mark/.append style={fill=red!80!black}\\%
mark=square*,only marks,point meta=explicit symbolic,brown!60!black,every mark/.append style={fill=brown!80!black}\\%
mark=pentagon*,only marks,point meta=explicit symbolic,black,every mark/.append style={solid,fill=black}\\%
}
\hspace*{-4cm}
\begin{tikzpicture}
\newcommand{\xx}{x};
\newcommand{\yy}{y};
\begin{groupplot}[group style={group size= 2 by 1,group name=myplot,horizontal sep=2.5cm,vertical sep = 3.5cm},cycle list name=mycolorlist,legend style={at={(1.,0.5)},anchor=west}]
\nextgroupplot[ylabel = {y},xlabel={x}]
\addplot+[discard if not={Label}{A},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{A}
\addplot+[discard if not={Label}{B},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{B}
\addplot+[ discard if not={Label}{C},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{C}
\addplot+[ discard if not={Label}{D},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{D}
\nextgroupplot[ylabel = {z},xlabel={x}]
\renewcommand{\yy}{z}
\addplot+[discard if not={Label}{A},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{A}
\addplot+[discard if not={Label}{B},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{B}
\addplot+[ discard if not={Label}{C},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{C}
\addplot+[ discard if not={Label}{D},unbounded coords=discard]table[meta=Label,y=\yy,x=\xx,col sep=comma] {data.csv};\addlegendentry{D}
\end{groupplot}
\end{tikzpicture}
\end{document}
在左图中,图例为假,棕色正方形实际上是对象 C,黑色五边形是对象 D(B 没有 y 值)。在右图中,C 不应该出现,因为它没有任何 z 属性值。
所以我知道基本上我可以单独获取每个属性并仅绘制好的对象,但我有很多不同的属性需要绘制,这会花费我大量的时间。
如果有人有解决方案我会非常高兴:)
谢谢
答案1
以下是一个相当严厉的解决方案,但它有效。
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{csvsimple}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfplotsset{plot coordinates/math parser=false}
\usepgfplotslibrary{groupplots}
\usepackage{pgfplotstable}
\begin{document}
\pgfplotstableset{col sep=comma,string type}
\pgfplotstableread{
Label,x,y,z
A,1,5,9
B,4,,7
C,6,5,
D,7,3,4
}\Table
%\pgfplotstabletypeset[columns/Label/.style={string type}]{\Table}% for debugging
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\edef\tempa{\thisrow{#1}}
\edef\tempb{#2}
\ifx\tempa\tempb
\else
\def\pgfmathresult{inf}
\fi
}
}
}
\tikzset{every mark/.append style={scale=3}}
\pgfplotscreateplotcyclelist{mycolorlist}{%
mark=10-pointed star,only marks,point meta=explicit symbolic,blue,every mark/.append style={fill=blue!80!black}\\%
mark=diamond*,only marks,point meta=explicit symbolic,red,every mark/.append style={fill=red!80!black}\\%
mark=square*,only marks,point meta=explicit symbolic,brown!60!black,every mark/.append style={fill=brown!80!black}\\%
mark=pentagon*,only marks,point meta=explicit symbolic,black,every mark/.append style={solid,fill=black}\\%
}
\hspace*{-4cm}
\begin{tikzpicture}
\newcommand{\xx}{x};
\newcommand{\yy}{y};
%\pgfplotstablegetrowsof{\Table}
%\let\rows=\pgfplotsretval
\begin{groupplot}[group style={group size= 2 by 1,group name=myplot,horizontal sep=2.5cm,vertical sep = 3.5cm},cycle list name=mycolorlist,legend style={at={(1.,0.5)},anchor=west}]
\nextgroupplot[ylabel = {y},xlabel={x}]
\pgfplotsinvokeforeach{0,1,2,3}{
\pgfplotstablegetelem{#1}{Label}\of{\Table}
\let\mark=\pgfplotsretval
\pgfplotstablegetelem{#1}{\xx}\of{\Table}
\let\x=\pgfplotsretval
\pgfplotstablegetelem{#1}{\yy}\of{\Table}
\let\y=\pgfplotsretval
\ifx\empty\x\else
\ifx\empty\y\else
\addplot+[only marks] coordinates {(\x,\y)};
\addlegendentryexpanded{\mark}
\fi\fi}
\nextgroupplot[ylabel = {z},xlabel={x}]
\renewcommand{\yy}{z}
\pgfplotsinvokeforeach{0,1,2,3}{
\pgfplotstablegetelem{#1}{Label}\of{\Table}
\let\mark=\pgfplotsretval
\pgfplotstablegetelem{#1}{\xx}\of{\Table}
\let\x=\pgfplotsretval
\pgfplotstablegetelem{#1}{\yy}\of{\Table}
\let\y=\pgfplotsretval
\ifx\empty\x\else
\ifx\empty\y\else
\addplot+[only marks] coordinates {(\x,\y)};
\addlegendentryexpanded{\mark}
\fi\fi}
\end{groupplot}
\end{tikzpicture}
\end{document}