4

Using this previously asked question I was able to plot Voronoi polygons from a set of generated data. I would like to annotate the plot further by doing the following:

  1. SOLVED BY MANIPULATING INPUT DATA: Add the triangle that is created from the three points.
  2. Lightly shade (opacity around 0.25) regions of the triangle that are within each Voronoi polygon a different color. So three shaded regions that are the polygons generated from the intersection of the Voronoi and triangle elements.
  3. Label each node generated from the points data file (red dots).

I have provided a MWE of what I have so far. Thanks in advance for any help/guidance.

enter image description here

Data in voronoiPoints.dat:

-0.135778 -0.651569 
-0.658113 1.655264 
1.645370 0.643096 

Data in voronoi.dat:

0.276155 0.654257
2.349036 -2.197525

0.276155 0.654257
-3.162349 -0.124321

0.276155 0.654257
1.694429 3.881949

Data in vornoiTriPoints.dat:

-0.135778 -0.651569 
-0.658113 1.655264 
1.645370 0.643096 
-0.135778 -0.651569 

Code that generates figure:

\documentclass[tikz,border=5]{standalone}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
  \begin{axis}[axis equal image,
    xtick=\empty,
    ytick=\empty]

    \addplot [only marks, red] table {voronoiPoints.dat};
    \addplot [no markers, blue] table {voronoiTriPoints.dat};
    \addplot [no markers, update limits=false] table {voronoi.dat};

  \end{axis}

\end{tikzpicture}

\end{document}
5

Here's one possibility using the fillbetween library:

enter image description here

The code:

\documentclass[tikz,border=5]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}

\usepackage{filecontents}

\begin{filecontents*}{voronoiPoints.dat}
1.645370 0.643096
-0.658113 1.655264 
-0.135778 -0.651569 
\end{filecontents*}

\begin{filecontents*}{voronoiTriPoints.dat}
-0.135778 -0.651569 
-0.658113 1.655264 
1.645370 0.643096 
-0.135778 -0.651569 
\end{filecontents*}

\begin{filecontents*}{voronoi.dat}
0.276155 0.654257
-3.162349 -0.124321

0.276155 0.654257
1.694429 3.881949

0.276155 0.654257
2.349036 -2.197525

0.276155 0.654257
-3.162349 -0.124321
\end{filecontents*}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
  axis equal image,
  xtick=\empty,
  ytick=\empty,
  set layers
]
  \addplot [only marks, red] table {voronoiPoints.dat};
  \addplot [no markers, blue,name path=triangle] table {voronoiTriPoints.dat};
  \addplot [no markers, update limits=false,name path=lines] table {voronoi.dat};
  \node[below=2pt] 
    at (axis cs:-0.135778,-0.651569) 
    {$a$};  
  \node[left=2pt] 
    at (axis cs:-0.658113,1.655264) 
    {$b$};
  \node[right=2pt] 
    at (axis cs:1.645370,0.643096) 
    {$c$};
  \clip[on layer=axis grid]
    (axis cs:-0.135778,-0.651569) -- 
    (axis cs:-0.658113,1.655264) -- 
    (axis cs:1.645370,0.643096) -- 
    (axis cs:-0.135778,-0.651569) -- cycle; 
  \addplot fill between[
    on layer=main,
    of=triangle and lines,
    split,
    every segment no 0/.style={blue,fill opacity=0},
    every segment no 1/.style={yellow,fill opacity=0.25},
    every segment no 2/.style={red,fill opacity=0.25},
    every segment no 3/.style={green,fill opacity=0.25},
  ];
\end{axis}
\end{tikzpicture}

\end{document}

I had to use clipping and layers to correct some problem with the filling; I'm sure there must be an easier way.

  • 1
    Thank you. I was hoping there may be a way to read in the locations from data files, but for such a small problem there isn't a need to. Good to know about the \clip command, it will be useful in the future. Also, thanks for reminding me about \begin{filecontents*}, I'll remember to use it going forward when posting data to SE. – chasely Aug 11 '15 at 17:15
4

Here's a way to do this using tkz-euclide:

\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\begin{document}

\begin{tikzpicture}
\tkzInit[xmin=0, xmax=3, ymin=1, ymax=4]
\tkzClip[space=1]

\tkzDefPoint(0,1){A} \tkzLabelPoint[below left](A){A}
\tkzDefPoint(3,2){B} \tkzLabelPoint[right](B){B}
\tkzDefPoint(1,4){C} \tkzLabelPoint[above](C){C}

\tkzCircumCenter(A,B,C)\tkzGetPoint{G}

\foreach \pointstart/\pointend in {A/B, B/C, C/A}{
    \tkzDefMidPoint(\pointstart,\pointend)\tkzGetPoint{\pointstart'}
    \tkzFindAngle(\pointstart,\pointstart',G)
    \pgfmathparse{int( or(\tkzAngleResult>180, \tkzAngleResult<0))}
    \ifnum\pgfmathresult=1
        \tkzDrawLine[add=0 and 1](G, \pointstart')
    \fi
}


\tkzClipPolygon(A,B,C)
\tkzDrawPolygon[draw=none, fill=gray, opacity=0.5](A,A',G,C')
\tkzDrawPolygon[draw=none, fill=gray, opacity=0.2](B,B',G,A')
\tkzDrawPolygon[draw=none, fill=gray, opacity=0.1](C,C',G,B')

\tkzDrawPolygon[color=red](A,B,C)
\end{tikzpicture}
\end{document}

The code might look a little bit more complicated than necessary, that's because it also handles the case where the circumcentre of the triangle lies outside the triangle:

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.