我正在尝试使用散点图来表示 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}