# How to draw a rectangle filled with random size circular pattern?

I wish to generate a rectangle with circular features present within (to represent water particles), something like this:

Which shows that the incoming radiation decreases with distance (as expressed by the shading of the arrow). This rather simplistic example was generated in power point, how would I draw this with tikz.

I can obviously draw a normal rectangle and arrow with:

\begin{tikzpicture}
\draw (0,0) rectangle (2,1);
\draw[>=stealth, <-] (1,0) -- (1,1);
\end{tikzpicture}


but how do I fill the rectangle with circles as shown and how do I apply a shading to the arrow?

• About the arrow: How would you draw an arrow filled with a gradient? – Jake Feb 18 '13 at 16:19
• @jake do you think picture mode would be easier? – David Carlisle Feb 18 '13 at 16:36
• @DavidCarlisle: Actually, in this case I think it might be. – Jake Feb 18 '13 at 16:37
• @Kate: (Just kidding, TikZ is definitely easier for something like this for everybody but David) – Jake Feb 18 '13 at 16:39
• – Torbjørn T. Feb 18 '13 at 16:41

The answer Torbjørn points in the comments is related, but the circles there have always the same radius.

Another approach:

\documentclass{article}

\usepackage{tikz}

\usepackage{xparse}

\tikzset{arrowstyle/.style n args={3}{draw=#2,arrowfill={#3}, single arrow,minimum height=#1, single arrow,

\NewDocumentCommand{\tikzfancyarrow}{O{2cm} O{FireBrick} O{top color=OrangeRed!20, bottom color=Red} m}{
\tikz[baseline=-0.5ex]\node [arrowstyle={#1}{#2}{#3}] {#4};
}

% Parameters

\def\height{5}
\def\width{10}
\def\numpoints{500}
\def\maxpointwidth{1.75}

\begin{document}

\begin{tikzpicture}
\path (0,0) rectangle (\width,\height);

\foreach \point in {1,...,\numpoints}{
\pgfmathparse{random()}
\pgfmathsetmacro\xpos{\width*\pgfmathresult}
\pgfmathparse{random()}
\pgfmathsetmacro\ypos{\height*\pgfmathresult}
\pgfmathrandom{0.1,\maxpointwidth}
\let\pointwidth\pgfmathresult

\node[circle,inner sep=\pointwidth pt,fill=blue!30] (point-\point) at (\xpos,\ypos) {};
}

\node [arrowstyle={\height cm}{black}{top color=orange,bottom color=yellow,shape border rotate=270}] at (\width/2,\height/2) {};

\end{tikzpicture}

\end{document}


This uses Fancy arrows with TikZ to create the gradient and the various parameters could be set in the preamble.

This could be probably an overkilling solution, but allows to achieve an higher customization:

\documentclass[tikz,png]{standalone}

\usepackage{tikz}

\usepackage{xparse}
\pgfkeys{/tikz/.cd,
height rect/.initial=5,
height rect/.get=\height,
height rect/.store in=\height,
width rect/.initial=10,
width rect/.get=\width,
width rect/.store in=\width,
num points/.initial=500,
num points/.get=\numpoints,
num points/.store in=\numpoints,
point width/.initial=1.5pt,
point width/.get=\maxpointwidth,
point width/.store in=\maxpointwidth,
point style type/.is choice,
point style type/fill/.style={fill=\pointcolor},
point style type/vertical shade/.style={top color=\pointtopcolor,bottom color=\pointbottomcolor},
point style type/horizontal shade/.style={left color=\pointleftcolor,right color=\pointrightcolor},
point style/.initial={/tikz/point style type/fill},
point style/.get=\pointstyle,
point style/.store in=\pointstyle,
point fill color/.initial=blue!30,
point fill color/.get=\pointcolor,
point fill color/.store in=\pointcolor,
point inner color/.initial=white,
point inner color/.get=\pointinnercolor,
point inner color/.store in=\pointinnercolor,
point outer color/.initial=blue!30,
point outer color/.get=\pointoutercolor,
point outer color/.store in=\pointoutercolor,
point top color/.initial=white,
point top color/.get=\pointtopcolor,
point top color/.store in=\pointtopcolor,
point bottom color/.initial=blue!30,
point bottom color/.get=\pointbottomcolor,
point bottom color/.store in=\pointbottomcolor,
point left color/.initial=blue!30,
point left color/.get=\pointleftcolor,
point left color/.store in=\pointleftcolor,
point right color/.initial=white,
point right color/.get=\pointrightcolor,
point right color/.store in=\pointrightcolor,
arrow top color/.initial=orange,
arrow top color/.get=\arrowtopcolor,
arrow top color/.store in=\arrowtopcolor,
arrow bottom color/.initial=yellow,
arrow bottom color/.get=\arrowbottomcolor,
arrow bottom color/.store in=\arrowbottomcolor,
arrow border color/.initial=black,
arrow border color/.get=\arrowbordercolor,
arrow border color/.store in=\arrowbordercolor,
}

\tikzset{arrowstyle/.style n args={3}{draw=#2,arrowfill={#3}, single arrow,minimum height=#1, single arrow,

\pgfkeys{/tikz/random point diagram/.code={
\path (0,0) rectangle (\width,\height);

\foreach \point in {1,...,\numpoints}{
\pgfmathparse{random()}
\pgfmathsetmacro\xpos{\width*\pgfmathresult}
\pgfmathparse{random()}
\pgfmathsetmacro\ypos{\height*\pgfmathresult}
\pgfmathparse{random()}
\pgfmathsetmacro\pointwidth{\maxpointwidth*\pgfmathresult}

\node[circle,inner sep=\pointwidth pt, \pointstyle] (point-\point) at (\xpos,\ypos) {};
}

\node [arrowstyle={\height cm}{\arrowbordercolor}{top color=\arrowtopcolor, bottom color=\arrowbottomcolor,shape border rotate=270}, anchor=north] at (\width/2,\height) {};
}
}

% that's just an alias for \node
\makeatletter
\def\drawdiagram{\tikz@path@overlay{node}}
\makeatother

\begin{document}

\begin{tikzpicture}
\drawdiagram[random point diagram] at (0,0) {};
\end{tikzpicture}

\begin{tikzpicture}[height rect=4,width rect=8,
num points=600,
point top color=white,
point bottom color=orange,
arrow border color=violet,
arrow top color=violet!50!magenta!80,
arrow bottom color=magenta!20]
\drawdiagram[random point diagram] at (0,0) {};
\end{tikzpicture}

\end{document}


The first example with the default values gives the previous picture, while the second customized example:

• With two arguments, pgfmathrandom{x,y} generates a random integer... – Paul Gaborit Feb 21 '13 at 22:06
• My original idea was in that direction, but then I thought: "maybe this ends up with points on the grid" so I used the other way. Do you think I'm introducing too much correlation in the point generation? – Claudio Fiandrino Feb 22 '13 at 8:24
• The call of pgfmathrandom with two arguments is used only for \pointwidth. – Paul Gaborit Feb 22 '13 at 8:45
• That's right: thanks. :) I'll edit in a minute. – Claudio Fiandrino Feb 22 '13 at 10:03
• You may use something like \pgfmathsetmacro\pointwidth{rnd*(\maxpointwidth-0.1)+0.1}... – Paul Gaborit Feb 22 '13 at 10:55

The \foreach loop construct and \pgfmathramdominteger are your friend:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,300}
{
\pgfmathrandominteger{\a}{5}{995}
\pgfmathrandominteger{\b}{5}{395}
\pgfmathrandominteger{\c}{30}{60}
};
\node at (5,2) [
right color=red!80!yellow,
left color = red!20!yellow,
single arrow,
single arrow tip angle=110,
minimum height=4cm,
inner sep=1pt,
rotate=270
] {};
\end{tikzpicture}
\end{document}


With thanks to Jake for the link to How would you draw an arrow filled with a gradient?, where I copied the arrow from.

Just for fun with PSTricks and it is not supposed to be the correctest way to go. Please feel free to edit.

\documentclass[pstricks,border=12pt]{standalone}
\SpecialCoor
{