2

I would like some help to get two ellipses around two sets of data on my final plot (d) like this:

enter image description here

Here is what I have so far:

\documentclass{article}
\usepackage{tikz,pgfplots}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{groupplots}
\usetikzlibrary{fit,shapes}

\newcommand{\datasetname}{check2.dat}
\begin{filecontents*}{\datasetname}
2     3
1     2
1     1
2     2
4     2
4     1
5     1
\end{filecontents*}

\pagestyle{empty}
\begin{document}
\begin{center}
\begin{tikzpicture}
\begin{groupplot}[group style={group size=2 by 2, horizontal sep=4em, vertical sep=5em}]
\nextgroupplot[xmin=-1, xmax=6, ymin=-1, ymax=5, legend style={font=\fontsize{7}{9}\selectfont}, title = (a) Original Data]
\addplot [only marks, line width = 0.3mm, mark=triangle*, red, mark options={scale=1.2}]table[x index=0, y index=1, col sep=comma, only marks,col sep=space] {\datasetname}; \addlegendentry{$Data$}

\nextgroupplot[xmin=-1, xmax=6, ymin=-1, ymax=5, legend style={font=\fontsize{7}{9}\selectfont}, title = (b) Data with Initial Centroids]
\addplot [only marks, line width = 0.3mm, mark=triangle*, red, mark options={scale=1.2}]table[x index=0, y index=1, col sep=comma, only marks,col sep=space] {\datasetname}; \addlegendentry{$Data$}
\addplot[mark=diamond*, blue, only marks] coordinates {(0,1)};\addlegendentry{$C1$}
\addplot[mark=diamond*, cyan, only marks] coordinates {(2,0)};\addlegendentry{$C2$}

\nextgroupplot[xmin=-1, xmax=6, ymin=-1, ymax=5, legend style={font=\fontsize{7}{9}\selectfont}, title = (c) Data with Centroids after First Iteration]
\addplot [only marks, line width = 0.3mm, mark=triangle*, red, mark options={scale=1.2}]table[x index=0, y index=1, col sep=comma, only marks,col sep=space] {\datasetname}; \addlegendentry{$Data$}
\addplot[mark=diamond*, blue, only marks] coordinates {(3.5,1.25)};\addlegendentry{$C1$}
\addplot[mark=diamond*, cyan, only marks] coordinates {(1.667,2.333)};\addlegendentry{$C2$}

\nextgroupplot[xmin=-1, xmax=6, ymin=-1, ymax=5, legend style={font=\fontsize{7}{9}\selectfont}, title = (d) Data with Centroids after Second Iteration]
\addplot [only marks, line width = 0.3mm, mark=triangle*, red, mark options={scale=1.2}]table[x index=0, y index=1, col sep=comma, only marks,col sep=space]{\datasetname};\addlegendentry{$Data$}
\addplot[mark=diamond*, blue, only marks] coordinates {(4.333,1.333)};\addlegendentry{$C1$}
\addplot[mark=diamond*, cyan, only marks] coordinates {(1.5,2.0)};\addlegendentry{$C2$}
%\node [pos=0.955,
%        shape=ellipse,
%        rotate=55,
%        minimum width=0.35*\pgfkeysvalueof{/pgfplots/width},
%        minimum height=0.2*\pgfkeysvalueof{/pgfplots/height},
%        very thick,
%        draw=green!75!black,
%        ] (ellipse) {};
\end{groupplot}

\end{tikzpicture}
\end{center}

\end{document}
  • I wanted to add the ellipses to the plots like that shown in the figure. – Joe Oct 20 '16 at 3:07
2

Here I present two solutions in one. One adding "manual" ellipsis on the given C1 and C2 coordinates and one "automatically" calculating the ellipsis using the fit library.

(I also "optimized" your code a bit, as you will see. Hopefully I added enough comments that you know what I did and why it works.)

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    \usetikzlibrary{
        fit,
        shapes,
        pgfplots.groupplots,
    }
    % create your own cycle list
    \pgfplotscreateplotcyclelist{my cycle list}{
            red,mark=triangle*,mark options={scale=1.2},\\
            blue,mark=diamond*,\\
            cyan,mark=diamond*,\\
    }
        \newcommand{\datasetname}{check2.dat}
    \begin{filecontents*}{\datasetname}
        2    3
        1    2
        1    1
        2    2
        4    2
        4    1
        5    1
    \end{filecontents*}
\begin{document}
    \begin{tikzpicture}
        \begin{groupplot}[
            group style={
                group size=2 by 2,
                horizontal sep=4em,
                vertical sep=5em,
            },
            % moved all common options here
            xmin=-1,
            xmax=6,
            ymin=-1,
            ymax=5,
            legend style={
                font=\fontsize{7}{9}\selectfont,
            },
            /tikz/only marks,
            % use created cycle list
            cycle list name=my cycle list,
            % just create legend once and apply it here
            legend entries={
                Data,
                $C1$,
                $C2$,
            },
        ]

        \nextgroupplot [
            title=(a) Original Data,
        ]
            \addplot table {\datasetname};

        \nextgroupplot [
            title=(b) Data with Initial Centroids,
        ]
            \addplot table {\datasetname};
            \addplot coordinates {(0,1)};
            \addplot coordinates {(2,0)};

        \nextgroupplot [
            title=(c) Data with Centroids after First Iteration,
        ]
            \addplot table {\datasetname};
            \addplot coordinates {(3.5,1.25)};
            \addplot coordinates {(1.667,2.333)};

        \nextgroupplot[
            title=(d) Data with Centroids after Second Iteration,
        ]
                % store number of data points
                \pgfplotstablegetrowsof{\datasetname}
                \pgfmathtruncatemacro{\N}{\pgfplotsretval-1}
            \addplot+ [
                % to find which coordinates are needed for the `fit' library
                % solution
                nodes near coords=a\coordindex,
            ] table {\datasetname}
                % set a coordinate on each data point
                % (needed for the `fit' library solution)
                \foreach \i in {0,...,\N} {
                    coordinate [pos=\i/\N] (a\i)
                }
            ;
        % add coordinates to the data points
        % (needed for the "manual" solution)
            \addplot coordinates {(4.333,1.333)}
                coordinate [pos=0] (C1)
            ;
            \addplot coordinates {(1.5,2.0)}
                coordinate [pos=0] (C2)
            ;

%        % ---------------------------------------------------------------------
%        % adding nodes manually (but centered on the points C1 and C2)
%            \node [
%                shape=ellipse,
%                rotate=-45,
%                minimum width=0.25*\pgfkeysvalueof{/pgfplots/width},
%                minimum height=0.2*\pgfkeysvalueof{/pgfplots/height},
%                very thick,
%                fill=orange!20,
%            ] at (C1) {};
%            \node [
%                shape=ellipse,
%                rotate=65,
%                minimum width=0.30*\pgfkeysvalueof{/pgfplots/width},
%                minimum height=0.2*\pgfkeysvalueof{/pgfplots/height},
%                very thick,
%                fill=green!20,
%            ] at (C2) {};
        % ---------------------------------------------------------------------
        % adding nodes automatically with the `fit' library
        % (but then they are not necessarily centered on
        %  the C1 and C2 coordinates)
            \node [
                shape=ellipse,
                very thick,
                fill=orange!20,
                %
                fit={(a4) (a5) (a6)},
                % adapt the found solution a bit by rotating 
                % and changing the size a bit
                rotate fit=-45,
                minimum width=0.25*\pgfkeysvalueof{/pgfplots/width},
            ] (C1 fit) {};
            \node [
                shape=ellipse,
                very thick,
                fill=green!20,
                fit={(a0) (a1) (a2) (a3)},
                rotate fit=-25,
            ] (C2 fit) {};

            % the names of the above "fit" nodes where just added to now show
            % where the centers of these nodes are
            \fill [black,radius=3pt]
                (C1 fit) circle --
                (C2 fit) circle
            ;
        % ---------------------------------------------------------------------

        \end{groupplot}
    \end{tikzpicture}
\end{document}

image showing the result of above code

  • Stefan. Sincerest THANK YOU for all your time and help. Your solution is very through. Thanks again! – Joe Oct 20 '16 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.