TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'd like to create the following plot (illustrating a population and a random sample) with tikz where the dots are created/placed randomly; all dots inside the circle, however, are supposed to be coloured in red:

enter image description here

Using answers based on previous (somewhat similar) questions, I was able to create the following plot.

\documentclass[tikz]{standalone}
\begin{document}
  \begin{tikzpicture}
    \draw (0,0) -- (4,0) -- (4,4) -- (0,4) -- cycle;
    \foreach \x in {1,...,40}
    {
      \pgfmathrandominteger{\a}{10}{390}
      \pgfmathrandominteger{\b}{10}{390}
      \fill (\a*0.01,\b*0.01) circle (0.1);
    };
    \draw (2,2) circle (1cm);
  \end{tikzpicture}
\end{document}

enter image description here

However, I have no clue how to color the dots inside the circle in red (I have a vague idea that involves basic geometry and ifelse by checking every dot if it is placed inside the circle... does that make sense?).

share|improve this question
    
a simpler way imho would be to draw some red dots inside a circle and some black ones outside, in two different loops... and maybe using polar coordinates would help! – Davide Jan 9 at 7:52
    
What happens to the ones on the boundary? – percusse Jan 9 at 8:56
up vote 12 down vote accepted

Mathematically, a circle with radius r with center at (a,b) is defined by the equation

(x-a)^2 + (y-b)^2 = r^2

So, to check if a point lies within this circle, you can check if the random points (x,y) satisfy

(x-a)^2 + (y-b)^2 <= r^2

i.e. they are less than r away from the center of the circle. If you use <=, then points on the border still count as "inside", if you use <, they won't.

To do that in TikZ, you can use the ifthenelse function provided by PGF Math. That is:

\pgfmathparse{ ifthenelse(condition, "value A", "value B")}

If the condition is satisfied, \pgfmathresult will contain "value A", if not it will contain "value B". We can use this to set the color either to "black" or "red":

\documentclass[tikz]{standalone}
\begin{document}
  \begin{tikzpicture}

    % Random seed for RNG
    \pgfmathsetseed{\number\pdfrandomseed}

    % Define circle parameters
    \newcommand{\cX}{2}
    \newcommand{\cY}{2}
    \newcommand{\cR}{1}

    \draw (0,0) -- (4,0) -- (4,4) -- (0,4) -- cycle;

    \foreach \x in {1,...,40}
    {
      % Find random numbers
      \pgfmathrandominteger{\a}{10}{390}
      \pgfmathrandominteger{\b}{10}{390}

      % Scale numbers nicely
      \pgfmathparse{0.01*\a}\let\a\pgfmathresult
      \pgfmathparse{0.01*\b}\let\b\pgfmathresult

      % Check if numbers are inside circle
      \pgfmathparse{ifthenelse((\a-\cX)^2 + (\b-\cY)^2 <= \cR^2,%
          "red",
          "black")}
        \fill[\pgfmathresult] (\a,\b) circle (0.1);
    };
    \draw (\cX,\cY) circle (\cR);
  \end{tikzpicture}
\end{document}

result

share|improve this answer

If you don't mind working in points, then the TikZ math library may be helpful. Here, points are rejected if they would lie on the border of the circle.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}[x=1pt,y=1pt]
\tikzmath{%
  coordinate \c, \p, \q;
  \q = (100, 100);
  \c = (30, 30);
  \R = 50;
  \r = 1;
  {
    \draw (-\qx, -\qy) rectangle (\qx, \qy);
    \draw [red] (\c) circle [radius=\R];
  };
  \x = \qx - \r; \y = \qy - \r;
  for \i in {0,...,100}{
    \p = (rand * \x, rand * \y);
    \v = veclen(\cx - \px, \cy - \py);
    if \v > (\R + \r) then {
      { \fill [black] (\p) circle [radius=\r]; };
    } else {
      if \v < (\R - \r) then {
        { \fill [red] (\p) circle [radius=\r]; };
      };
    };
  };
}
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer

Here is one "clipping mask" solution:

\documentclass[varwidth, border=7pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{fadings}

\begin{document}
  % define clip mask with random points
  \begin{tikzfadingfrompicture}[name=rndpts]
    \fill[transparent!0] foreach ~ in {1,...,100}{(rand,rand) circle (0.02)};
  \end{tikzfadingfrompicture}
  % use it to clip rectangle and circle
  \begin{tikzpicture}
    \begin{scope}
      \fill[scope fading=rndpts, fit fading=true] (0,0) rectangle (4,4);
      \fill[red] (2,2) circle (1cm);
    \end{scope}
    \draw (0,0) rectangle (4,4);
    \draw[red] (2,2) circle (1cm);
  \end{tikzpicture}
\end{document}

share|improve this answer

Metapost is also very good at this sort of diagram.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

numeric N, s, r;
N = 100; % population
s = 300; % size of square
r = 40; % radius of circle
z0 = (200,160); % center of circle;
color selected; selected = .73 red;

for i=1 upto N:
   z[i] = (uniformdeviate s, uniformdeviate s);
   drawdot z[i] withpen pencircle scaled 4 
     if r > length(z[i]-z0): withcolor selected fi;
endfor

draw fullcircle scaled 2r shifted z0 withcolor selected;
draw unitsquare scaled s;

endfig;
end.
share|improve this answer

Here's yet another solution that:

  1. Sets the circle whose center defines the coordinate center, with a radius \ra (expressed in pt).
  2. A \foreach loop that creates 200 random points, but you can change the number.
  3. A measurement is done between center and each dot point.
  4. Using an \if statement, if the length is above 50pt, dots will be standard black, otherwise, they'll be colored red.

Output

enter image description here

Code

\documentclass[margin=20pt]{standalone}
\usepackage{tikz,tkz-euclide}
\usetkzobj{all}

\usetikzlibrary{calc}
\newcommand\ra{50}

\begin{document}
\begin{tikzpicture}
\draw (1,2) coordinate (center) circle (\ra pt);

\foreach \point in {1,...,200}{%
    \pgfmathparse{rand}
    \pgfmathsetmacro\xdot{-7*\pgfmathresult}
    \pgfmathparse{rand}
    \pgfmathsetmacro\ydot{-5*\pgfmathresult}
%
    \coordinate (c\point) at (\xdot,\ydot);
    \tkzCalcLength(center,c\point) \tkzGetLength{myl}
    \pgfmathtruncatemacro\distance{\myl}
    \ifnum\distance>\ra
        \fill (c\point) circle (2pt);
    \else
        \fill[red] (c\point) circle (2pt);
    \fi
}%
\end{tikzpicture}
\end{document}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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