如何在函数条件下为坐标着色

如何在函数条件下为坐标着色

如果图中某些点与某个聚类质心坐标的欧几里得距离小于或大于与另一个聚类质心的欧几里得距离,我想更改这些点的颜色。我尝试了不同的方法,但总觉得有些东西无法编译。我为每个质心创建了两个 tikz 函数 dist1 和 dist2,并尝试在 addplot 中使用点元数据来更改标记的颜色,

\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{tikzmark,math}
\usetikzlibrary{arrows.meta}
\usepackage{calc}
\usepackage{filecontents}

\begin{filecontents*}{myplot.csv}
x,y
0.1566,1.8781
0.3431,1.5972
0.4492,1.714
0.6587,1.3417
0.7074,0.8094
1.1474,0.4845
1.3499,1.1533
1.8312,1.2761
2.1437,0.8622
2.2518,1.7449
\end{filecontents*}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[        width=10cm,        height=10cm,        xlabel={$x$},        ylabel={$y$},        scatter/classes={            red={mark=square*,red},            blue={mark=triangle*,blue}        }    ]
    
    % Declare functions to compute distances to CC1 and CC2
    % Calculate distance to CC1 and CC2
    \tikzmath{
      coordinate \centroid1, \centroid2;
      \centroid1 = (3.5, 2.0);
      \centroid2 = (2.0, 1.0);
      function dist1(\x,\y) {
        return sqrt((\x - \centroid1.x)^2 + (\y - \centroid1.y)^2);
      };
      function dist2(\x,\y) {
        return sqrt((\x - \centroid2.x)^2 + (\y - \centroid2.y)^2);
      };
    }
    
    
    \addplot[
      mark=*,
      only marks,
      point meta=ifthenelse(dist1(\thisrow{x}, \thisrow{y}) < dist2(\thisrow{x}, \thisrow{y}), "red", "blue")
    ] table {myplot.csv};
    
    
    \end{axis}
\end{tikzpicture}

\end{document}

答案1

我不知道将 tikz math 与 pgfplots 混合是否容易,以及是否可以说服 point meta 解析表达式并将生成的字符串解释为样式。很可能是可能的,但我无法做到这一点。但是,可以使用更低级别的代码scatter/@pre marker code来实现条件着色。此代码可用于比较给定点与两个质心的距离,并相应地设置标记的样式。

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

\begin{filecontents*}[overwrite]{myplot.csv}
x,y
0.1566,1.8781
0.3431,1.5972
0.4492,1.714
0.6587,1.3417
0.7074,0.8094
1.1474,0.4845
1.3499,1.1533
1.8312,1.2761
2.1437,0.8622
2.2518,1.7449
\end{filecontents*}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[width=10cm,height=10cm,xlabel={$x$},ylabel={$y$},
        declare function={cx1=1.5;cy1=2.0;cx2=2.0;cy2=1.0;
            dist(\x,\y,\u,\v)=sqrt((\x-\u)*(\x-\u)+(\y-\v)*(\y-\v));
            dist1(\x,\y)=dist(\x,\y,cx1,cy1);
            dist2(\x,\y)=dist(\x,\y,cx2,cy2);
            }    
        ]    
    
    \addplot[
      mark=*,
      only marks,
      scatter,
      visualization depends on={value \thisrow{x} \as \myx},
      visualization depends on={value \thisrow{y} \as \myy},
       scatter/@pre marker code/.code={%
         \pgfmathparse{int(dist1(\myx,\myy)<dist2(\myx,\myy)?1:0)}%
         \ifcase\pgfmathresult
            \tikzset{my mark/.style={mark=square*,red}}
         \or 
            \tikzset{my mark/.style={mark=triangle*,blue}}
         \fi
         \begin{scope}[my mark]
        },
        scatter/@post marker code/.code={\end{scope}}
    ] table[col sep=comma] {myplot.csv};
    \end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

请注意,我删除了未使用的包,并且还更改了一个质心的坐标,使用问题中给出的值,所有标记看起来都相同,因为一个距离总是小于另一个距离。

相关内容