常规的 pgfplots-colormap 是一维的。它需要一个元值并推断相应的颜色。但是,我有三个元值,而不是一个元值,每个元值都与一个值相关联。
为了简单起见,我们假设三个元值(,,n1
)始终为正数且总和为 1,则颜色混合规则很简单:。n2
n3
color = n1 * color1 + n2 * color2 + n3 * color3
给定这个元数据(来自表格),我想用适当混合的颜色为网格着色。
基于这个问题我已经弄清楚可以明确提供 RGB 值。但我无法正确得出公式。特别是,我不知道如何访问已定义颜色的 RBG 值。
下面的代码说明了这个问题:
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}
\begin{document}
\definecolor{color1}{red}
\definecolor{color2}{cyan}
\definecolor{color3}{yellow}
\begin{tikzpicture}
\begin{axis}
\addplot3[surf, mesh/color input=explicit mathparse,
point meta/symbolic={\thisrow{n1}, \thisrow{n2}, \thisrow{n3} } % problematic line
% how do I mix the colors here so that color = n1 * color1 + n2 * color2 + n3 * color3?
] table[] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}
数据文件data.csv
包含如下内容:
x,y,z,n1,n2,n3
-1.0,-1.0,0,0.243910357114819,0.2666555209251139,0.4894341219600671
-0.5,-1.0,0,0.3013791690628364,0.2152633649632925,0.48335746597387114
0.0,-1.0,0,0.5021192190297844,0.16757485484227622,0.3303059261279394
0.5,-1.0,0,0.5979647407883067,0.14009437103777442,0.2619408881739188
-1.0,-0.5,0,0.164292920913273,0.2655366172800358,0.5701704618066912
-0.5,-0.5,0,0.1355599513531367,0.2040615139888475,0.6603785346580158
0.0,-0.5,0,0.4083574985065873,0.2049743531246625,0.3866681483687502
0.5,-0.5,0,0.4880958726415202,0.2436859445670927,0.2682181827913871
-1.0,0.0,0,0.13994145285914186,0.26041474337409753,0.5996438037667606
-0.5,0.0,0,0.08883801351075463,0.19202791600642005,0.7191340704828253
0.0,0.0,0,0.1290235911491401,0.22620482004695425,0.6447715888039056
0.5,0.0,0,0.1901399752789048,0.49178772678672855,0.31807229793436664
-1.0,0.5,0,0.15879820629696065,0.2619254086260544,0.579276385076985
-0.5,0.5,0,0.11257406503995221,0.18855240164294096,0.6988735333171068
0.0,0.5,0,0.09915126016628552,0.243518553933322,0.6573301859003925
0.5,0.5,0,0.0914288508897056,0.5882997108532986,0.3202714382569958
答案1
欢迎来到 TeX.SE!这是我对这个有趣问题的解决方案:
\begin{filecontents*}{my-data.csv}
x y z n1 n2 n3
0.0 0.0 0.0 0.0 0.0 0.0
1.0 0.0 0.0 1.0 0.0 0.0
0.0 1.0 0.0 0.0 1.0 0.0
1.0 1.0 1.0 0.0 0.0 1.0
\end{filecontents*}
\documentclass[tikz, border=2mm]{standalone}
\usepackage{xparse}
\usepackage{pgfplots}
\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=1.16}
% Each point of the plot will be assigned a color which is a mix of these
% three colors according to the weights given by columns n1, n2 and n3 of the
% data point, respectively.
\definecolor{color1}{rgb}{0.1,1.0,0.5}
\definecolor{color2}{rgb}{0.6,0.2,1.0}
\definecolor{color3}{rgb}{1.0,0.6,0.3}
% Extract the color components into 9 macros so that accessing each component
% when drawing the plot is as fast as possible. The target control sequences
% are \color<num>r, \color<num>g and \color<num>b where <num> is I, II or III
% (corresponding to the three colors 'color1', 'color2' and 'color3').
\ExplSyntaxOn
\int_new:N \l__minze_color_index_int
\seq_new:N \l__minze_color_components_seq
\clist_map_inline:nn { color1, color2, color3 }
{
\int_incr:N \l__minze_color_index_int
\extractcolorspecs {#1} { \l_tmpa_tl } { \l_tmpb_tl }
\seq_set_split:NnV \l__minze_color_components_seq { , } \l_tmpb_tl
\clist_map_inline:nn { r, g, b }
{
\seq_pop_left:NN \l__minze_color_components_seq \l_tmpa_tl
\cs_new_nopar:cpx
{ color \int_to_Roman:n { \l__minze_color_index_int } ##1 }
{ \tl_use:N \l_tmpa_tl }
}
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}[font=\scriptsize]
\begin{axis}[xlabel=$x$, ylabel=$y$, zlabel=$z$, z label style={rotate=-90}]
\addplot3 [
surf, mesh/color input=explicit mathparse,
patch type=bilinear, shader=interp,
point meta/symbolic={
(\thisrow{n1}*\colorIr + \thisrow{n2}*\colorIIr + \thisrow{n3}*\colorIIIr)
/ (\thisrow{n1} + \thisrow{n2} + \thisrow{n3}),
(\thisrow{n1}*\colorIg + \thisrow{n2}*\colorIIg + \thisrow{n3}*\colorIIIg)
/ (\thisrow{n1} + \thisrow{n2} + \thisrow{n3}),
(\thisrow{n1}*\colorIb + \thisrow{n2}*\colorIIb + \thisrow{n3}*\colorIIIb)
/ (\thisrow{n1} + \thisrow{n2} + \thisrow{n3})
},
] table[x=x, y=y, z=z] {my-data.csv};
% Color legend
\begin{scope}[nodes={minimum width=0.5cm, minimum height=0.25cm,
inner sep=0, draw=black, right, label distance=2mm}]
\coordinate (p) at (rel axis cs:0.3,0.5,1.1);
\path (p)
node[fill=color1, label=right:{color 1}] (node 1) {}
++(axis direction cs:0,0,-0.15)
node[fill=color2, label=right:{color 2}] (node 2) {}
++(axis direction cs:0,0,-0.15)
node[fill=color3, label=right:{color 3}] (node 3) {};
\end{scope}
\end{axis}
\end{tikzpicture}
\end{document}
这符合来自文件的输入数据my-data.csv
:
(0,0,0) 处的点有 (n 1 , n 2 , n 3 ) = (0,0,0) → 黑色;
(1,0,0) 处的点具有 (n 1 , n 2 , n 3 ) = (1,0,0) → 自定义颜色
color1
;(0,1,0) 处的点有 (n 1 , n 2 , n 3 ) = (0,1,0) → 自定义颜色
color2
;位于 (1,1,1) 处的点具有 (n 1 , n 2 , n 3 ) = (0,0,1) → 自定义颜色
color3
。
网格的每个点都被分配一种颜色,该颜色是颜色的混合color1
,color2
和根据数据点color3
分别由n1
、n2
和列给出的权重。n3
不需要确保 n1 + n2 + n3 = 1,因为我的代码在适当的地方除以 n1 + n2 + n3。
如果我们获取经过修改的您的数据文件是坐标(你们的坐标都是相等的),在调用的选项col sep=comma
中使用,并在选项中(因为这次,我在轴外绘制了图例,我不希望它被剪掉),我们得到:table
\addplot3 [...] table[...]
clip=false
axis
\begin{filecontents*}{data.csv}
x,y,z,n1,n2,n3
-1.0,-1.0,0,0.243910357114819,0.2666555209251139,0.4894341219600671
-0.5,-1.0,0,0.3013791690628364,0.2152633649632925,0.48335746597387114
0.0,-1.0,0,0.5021192190297844,0.16757485484227622,0.3303059261279394
0.5,-1.0,0,0.5979647407883067,0.14009437103777442,0.2619408881739188
-1.0,-0.5,0.2,0.164292920913273,0.2655366172800358,0.5701704618066912
-0.5,-0.5,0.2,0.1355599513531367,0.2040615139888475,0.6603785346580158
0.0,-0.5,0.2,0.4083574985065873,0.2049743531246625,0.3866681483687502
0.5,-0.5,0.2,0.4880958726415202,0.2436859445670927,0.2682181827913871
-1.0,0.0,0.9,0.13994145285914186,0.26041474337409753,0.5996438037667606
-0.5,0.0,0.9,0.08883801351075463,0.19202791600642005,0.7191340704828253
0.0,0.0,0.9,0.1290235911491401,0.22620482004695425,0.6447715888039056
0.5,0.0,0.9,0.1901399752789048,0.49178772678672855,0.31807229793436664
-1.0,0.5,1.2,0.15879820629696065,0.2619254086260544,0.579276385076985
-0.5,0.5,1.6,0.11257406503995221,0.18855240164294096,0.6988735333171068
0.0,0.5,1.6,0.09915126016628552,0.243518553933322,0.6573301859003925
0.5,0.5,1.4,0.0914288508897056,0.5882997108532986,0.3202714382569958
\end{filecontents*}
\documentclass[tikz, border=2mm]{standalone}
\usepackage{xparse}
\usepackage{pgfplots}
\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=1.16}
% Each point of the plot will be assigned a color which is a mix of these
% three colors according to the weights given by columns n1, n2 and n3 of the
% data point, respectively.
\definecolor{color1}{rgb}{0.1,1.0,0.5}
\definecolor{color2}{rgb}{0.6,0.2,1.0}
\definecolor{color3}{rgb}{1.0,0.6,0.3}
% Extract the color components into 9 macros so that accessing each component
% when drawing the plot is as fast as possible. The target control sequences
% are \color<num>r, \color<num>g and \color<num>b where <num> is I, II or III
% (corresponding to the three colors 'color1', 'color2' and 'color3').
\ExplSyntaxOn
\int_new:N \l__minze_color_index_int
\seq_new:N \l__minze_color_components_seq
\clist_map_inline:nn { color1, color2, color3 }
{
\int_incr:N \l__minze_color_index_int
\extractcolorspecs {#1} { \l_tmpa_tl } { \l_tmpb_tl }
\seq_set_split:NnV \l__minze_color_components_seq { , } \l_tmpb_tl
\clist_map_inline:nn { r, g, b }
{
\seq_pop_left:NN \l__minze_color_components_seq \l_tmpa_tl
\cs_new_nopar:cpx
{ color \int_to_Roman:n { \l__minze_color_index_int } ##1 }
{ \tl_use:N \l_tmpa_tl }
}
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}[font=\scriptsize]
\begin{axis}[xlabel=$x$, ylabel=$y$, zlabel=$z$, z label style={rotate=-90},
clip=false]
\addplot3 [
surf, mesh/color input=explicit mathparse,
patch type=bilinear, shader=interp,
point meta/symbolic={
(\thisrow{n1}*\colorIr + \thisrow{n2}*\colorIIr + \thisrow{n3}*\colorIIIr)
/ (\thisrow{n1} + \thisrow{n2} + \thisrow{n3}),
(\thisrow{n1}*\colorIg + \thisrow{n2}*\colorIIg + \thisrow{n3}*\colorIIIg)
/ (\thisrow{n1} + \thisrow{n2} + \thisrow{n3}),
(\thisrow{n1}*\colorIb + \thisrow{n2}*\colorIIb + \thisrow{n3}*\colorIIIb)
/ (\thisrow{n1} + \thisrow{n2} + \thisrow{n3})
},
] table[x=x, y=y, z=z, col sep=comma] {data.csv};
% Color legend
\begin{scope}[nodes={minimum width=0.5cm, minimum height=0.25cm,
inner sep=0, draw=black, right, label distance=2mm}]
\coordinate (p) at (rel axis cs:-0.4,0.5,1.1);
\path (p)
node[fill=color1, label=right:{color 1}] (node 1) {}
++(axis direction cs:0,0,-0.15)
node[fill=color2, label=right:{color 2}] (node 2) {}
++(axis direction cs:0,0,-0.15)
node[fill=color3, label=right:{color 3}] (node 3) {};
\end{scope}
\end{axis}
\end{tikzpicture}
\end{document}