PGFPlots:从一列绘制颜色,从另一列绘制形状?

PGFPlots:从一列绘制颜色,从另一列绘制形状?

我正在尝试使用散点图来表示 4 维数据。

问题: 是否可以从一列绘制颜色,从另一列绘制形状?

我能做什么

例如,我可以使用以下 R 代码:

library(tidyverse)

set.seed(1)
mydata = data.frame(x = runif(20),
                     y = runif(20))
mydata = mydata %>%
    mutate(x = round(x, 2)) %>%
    mutate(y = round(y, 2)) %>%
    mutate(color = round(x - y,2)) %>%
    mutate(shape = gl(3,20/3))
#write_csv(mydata, 'color-and-shape.csv')

ggplot(mydata, aes(x = x, y = y, color = color, shape = shape)) +
    geom_point(size = 5)
ggsave('color-and-shape.png', width = 7, height = 5)

绘制以下图表:

在此处输入图片描述

我可以编写以下 LaTeX 代码:

\documentclass[margin=2pt]{standalone}

\usepackage{filecontents}
\begin{filecontents*}{color-and-shape.csv}
x,y,color,shape
0.27,0.93,-0.66,1
0.37,0.21,0.16,1
0.57,0.65,-0.08,1
0.91,0.13,0.78,1
0.2,0.27,-0.07,1
0.9,0.39,0.51,1
0.94,0.01,0.93,2
0.66,0.38,0.28,2
0.63,0.87,-0.24,2
0.06,0.34,-0.28,2
0.21,0.48,-0.27,2
0.18,0.6,-0.42,2
0.69,0.49,0.2,3
0.38,0.19,0.19,3
0.77,0.83,-0.06,3
0.5,0.67,-0.17,3
0.72,0.79,-0.07,3
0.99,0.11,0.88,3
0.38,0.72,-0.34,1
0.78,0.41,0.37,1
\end{filecontents*}

\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=newest}

\begin{document}
\begin{tikzpicture}
\begin{axis}[colorbar horizontal]
    \addplot[scatter,only marks,point meta=explicit] table
        [x=x,y=y,meta=color,col sep=comma] {color-and-shape.csv};
\end{axis}
\end{tikzpicture}
\end{document}

绘制以下图表:

在此处输入图片描述

我可以获得彩色图,但我不知道如何同时获取可变的标记形状。

答案1

正如前面提到的在问题下方评论您可以通过使用 3 个\addplot命令与用户定义的过滤器组合来实现这一点discard if not

有关更多详细信息,请查看代码中的注释。

% used PGFPlots v1.15
\begin{filecontents*}{color-and-shape.csv}
x,y,color,shape
0.27,0.93,-0.66,1
0.37,0.21,0.16,1
0.57,0.65,-0.08,1
0.91,0.13,0.78,1
0.2,0.27,-0.07,1
0.9,0.39,0.51,1
0.94,0.01,0.93,2
0.66,0.38,0.28,2
0.63,0.87,-0.24,2
0.06,0.34,-0.28,2
0.21,0.48,-0.27,2
0.18,0.6,-0.42,2
0.69,0.49,0.2,3
0.38,0.19,0.19,3
0.77,0.83,-0.06,3
0.5,0.67,-0.17,3
0.72,0.79,-0.07,3
0.99,0.11,0.88,3
0.38,0.72,-0.34,1
0.78,0.41,0.37,1
\end{filecontents*}
\documentclass[margin=5pt]{standalone}
\usepackage{pgfplots}
    \pgfplotsset{
        % create filter that discards all entries from the table row
        % given as first argument of this style with the value not equal
        % to the second argument of this style
        discard if not/.style 2 args={
            % suppress LOG messages about the filtered points
            filter discard warning=false,
            x filter/.append code={
                \edef\tempa{\thisrow{#1}}
                \edef\tempb{#2}
                \ifx\tempa\tempb
                \else
                    \def\pgfmathresult{NaN}
                \fi
            },
        },
    }
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        colorbar horizontal,
        only marks,
        scatter,
        point meta=explicit,
        % ---------------------------------------------------------------------
        % set point meta min and max values, if you want to
        point meta min=-1,
        point meta max=+1,
        % choose an appropriate `cycle list name' that has different marks
        cycle list name=mark list,
        % so it looks better in the legend I set the default fill color to gray
        mark list fill=gray,
        % I don't like the default `colormap', so I have changed it
        colormap name=viridis,
        % to not overlap some points I have moved the legend outside of the plot
        legend pos=outer north east,
        legend cell align=left,
        % ---------------------------------------------------------------------
    ]

        % added a "dummy" legend entry to create a common header
        \addlegendimage{empty legend}
        \addlegendentry[align=left]{shape \\ number}

        % cycle through all different shape numbers
        \pgfplotsforeachungrouped \i in {1,...,3} {
            \addplot+ table [
                x=x,
                y=y,
                meta=color,
                col sep=comma,
                % use the above defined style here
                discard if not={shape}{\i},
            ] {color-and-shape.csv};
                % add a legend entry that contains the shape number
                \addlegendentryexpanded{\ \i};
        }
    \end{axis}
\end{tikzpicture}
\end{document}

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

相关内容