Problemas de legenda quando faltam coordenadas

Problemas de legenda quando faltam coordenadas

Encontrei um pequeno problema quando quis fazer gráficos dos meus dados. Basicamente, estou trabalhando em 10 objetos diferentes, que possuem diversas propriedades. Então eu tenho um arquivo csv, com 10 linhas e várias colunas representando cada propriedade do objeto. Cada linha possui alguns "espaços em branco", o que significa que não sabemos o valor da propriedade deste objeto. Isso é representado no MWE a seguir por 4 objetos A,B,C e D que possuem propriedades x,y,z. Sabemos x, y e z para A e D, apenas x e z para B e x e y para C.

\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}

Isso me dá os seguintes gráficos: insira a descrição da imagem aqui

No gráfico da esquerda, a legenda é falsa, o quadrado marrom é na verdade o objeto C e o pentágono preto o objeto D (B não tem valor para y). No gráfico da direita, C não deve aparecer porque não possui nenhum valor para a propriedade z.

Então, eu sei que basicamente poderia pegar cada propriedade individualmente e plotar apenas os objetos bons, mas tenho muitas propriedades diferentes para plotar e levaria muito tempo para fazer isso.

Ficarei muito feliz se alguém tiver uma solução :)

Obrigado

Responder1

A seguir está uma solução pesada, mas funciona.

\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}

demonstração

informação relacionada