6

I am making a custom resume template and want to incorporate a sort-of pie chart to illustrate relative skill-set experience. When searching google I came across this plot which is fairly similar to the effect I am trying to achieve:

Size-varying pie chart

Unfortunately my experience in tikz is lacking for something like this, and I was wondering if someone can point me towards some code which does something similar which I can modify, or point me to resources beyond just the basic tikz manual, which i've gone through.

2

4 Answers 4

8

Not much in the way of instructions but it should be fairly straightforward to see how to customise things.

Note that it is the (shifted) radius that indicates the number of years experience rather than the area of the shaded sector. This gives an inflated impression of the experience level (which may or may not be desired).

\documentclass[tikz,border=5]{standalone}
\renewcommand\familydefault\sfdefault
\usepackage{filecontents}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{colormaps}

\pgfplotstableset{col sep=comma}
\begin{filecontents}{programming.csv}
language,years
Perl,8
HTML,5.5
CSS,5.5
javascript,5.5
SQL,8
Java,10
Ruby,4
Python,4
c{/}c++,6
\end{filecontents}

\pgfplotstableread{programming.csv}\data
\pgfplotstablegetrowsof{\data}
\pgfmathsetmacro{\nrows}{int(\pgfplotsretval-1)}  
\pgfmathsetmacro{\step}{360/\pgfplotsretval}  

\pgfplotsset{colormap/hsv}
\tikzset{%
  sector/.style={
    /utils/exec=\pgfmathparse{int(#1/\nrows*900+50)}%
      \pgfplotscolormapdefinemappedcolor{\pgfmathresult},
    top color=mapped color!75!black,
    bottom color=mapped color,
    shading angle=#1*\step+\step/2-90,
    draw=white,
    very thick
  }
}
\begin{document}
\begin{tikzpicture}

\foreach \i [evaluate={\j=\i+1;}] in {0,...,\nrows}{
  \pgfplotstablegetelem{\i}{language}\of{\data}\let\language=\pgfplotsretval
  \pgfplotstablegetelem{\i}{years}\of{\data}\let\years=\pgfplotsretval
  \pgfmathsetmacro\years{\years/2}
  \path [sector=\i] (\i*\step:1) (\i*\step:1+\years) 
    arc (\i*\step:\j*\step:1+\years) -- (\j*\step:1)
    arc (\j*\step:\i*\step:1) -- cycle;
  \pgfmathparse{int(\years>2)}
  \ifnum\pgfmathresult=1
    \node [text=white, font=\bfseries] 
      at (\i*\step+\step/2:1+\years/2) {\language};
  \else
    \node [text=black, font=\bfseries]
      at (\i*\step+\step/2:1+\years+1/2) {\language};
  \fi
}
\end{tikzpicture}
\end{document}

enter image description here

5

A TikZ solution without pgfplots:

I defines a new command \vardonut{} that takes as input a comma-seperated list of <language>/<experience>/<colour>

So

\begin{tikzpicture}
    \vardonut{
        perl       / 6 /Blue, 
        html       / 5 /ForestGreen, 
        css        / 5 /Red, 
        javascript / 4 /Cyan, 
        sql        / 4 /Magenta, 
        java       / 3 /Blue, 
        ruby       / 2 /Red, 
        python     / 2 /ForestGreen, 
        {c/\cc}    / 2 /Cyan, 
        .net       / 1 /Magenta%
    }
\end{tikzpicture}

will get you:

enter image description here

The command \vardonut{} draws for each piece of the donut two arcs with a different radius and connects them. Afterwards the language text is put on top of it:

\newcommand{\vardonut}[1]{
    \newcounter{num}
    \foreach \content/\size/\colour in {#1}
        \stepcounter{num};
    \foreach \content/\size/\colour [count=\i] in {#1}{
        \draw[white,very thick,top color=\colour!50!black, bottom color=\colour, shading angle={-90+360/\thenum/2+(\i-1)*360/\thenum}] 
        ({2*cos((\i-1)*360/\thenum)},{2*sin((\i-1)*360/\thenum)}) arc[radius = 2, start angle={(\i-1)*360/\thenum}, delta angle=360/\thenum] --
        ({(2+\size)*cos(\i*360/\thenum)},{(2+\size)*sin(\i*360/\thenum)}) arc[radius = {2+\size}, start angle={\i*360/\thenum}, delta angle=-360/\thenum] -- 
        cycle;
        \node[white,font=\large] at ({(\i-1)*360/\thenum+360/\thenum/2}:{\size/2+2}) {\content};
    }
}

The entire document:

\documentclass[border=2mm]{standalone}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tikz}

\newcommand{\cc}{c\nolinebreak\hspace{-.05em}\raisebox{.2ex}{\tiny\bf +}\nolinebreak\hspace{-.10em}\raisebox{.2ex}{\tiny\bf +}}

\newcommand{\vardonut}[1]{
    \newcounter{num}
    \foreach \content/\size/\colour in {#1}
        \stepcounter{num};
    \foreach \content/\size/\colour [count=\i] in {#1}{
        \draw[white,very thick,top color=\colour!50!black, bottom color=\colour, shading angle={-90+360/\thenum/2+(\i-1)*360/\thenum}] 
        ({2*cos((\i-1)*360/\thenum)},{2*sin((\i-1)*360/\thenum)}) arc[radius = 2, start angle={(\i-1)*360/\thenum}, delta angle=360/\thenum] --
        ({(2+\size)*cos(\i*360/\thenum)},{(2+\size)*sin(\i*360/\thenum)}) arc[radius = {2+\size}, start angle={\i*360/\thenum}, delta angle=-360/\thenum] -- 
        cycle;
        \node[white,font=\large] at ({(\i-1)*360/\thenum+360/\thenum/2}:{\size/2+2}) {\content};
    }
}

\begin{document}
    \begin{tikzpicture}
        \vardonut{perl/6/Blue, html/5/ForestGreen, css/5/Red, javascript/4/Cyan, sql/4/Magenta, java/3/Blue, ruby/2/Red, python/2/ForestGreen, {c/\cc}/2/Cyan, .net/1/Magenta}
    \end{tikzpicture}
\end{document}
3

In case others are interested, I modified Mark Wibrow's answer to plot each segment such that the relative area corresponds to the number of years associated with each language, rather than the radius. The main thing to note is that with the code as currently written, you have to have the smallest value appear first in the table.

By Area

\documentclass[tikz,border=5]{standalone}
\renewcommand\familydefault\sfdefault
\usepackage{filecontents}
\usepackage[nomessages]{fp} % for calculations
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{colormaps}

\pgfplotstableset{col sep=comma}
\begin{filecontents}{programming.csv}
language,years
Ruby,4
Python,4
c{/}c++,6
Perl,8
HTML,5.5
CSS,5.5
javascript,5.5
SQL,8
Java,10
\end{filecontents}

\pgfplotstableread{programming.csv}\data
\pgfplotstablegetrowsof{\data}
\pgfmathsetmacro{\nrows}{int(\pgfplotsretval-1)}  
\pgfmathsetmacro{\step}{360/\pgfplotsretval}  
\pgfplotstablegetelem{0}{years}\of{\data}\let\basenum=\pgfplotsretval


\pgfplotstablecreatecol[
    create col/assign/.code={%
        \getthisrow{years}\entry
        \FPeval\basearea{3.14159*(\basenum+1)*(\basenum+1)/\nrows - 3.14159/\nrows}
        \FPeval\stepone{((\entry/\basenum)*\basearea*\nrows)/3.14159 + 1}
        \FProot\steptwo{\stepone}{2}
        \FPeval\stepthree{\steptwo-1}
        \edef\entry{\stepthree}%
        \pgfkeyslet{/pgfplots/table/create col/next content}\entry
    }]
    {adjustedradius}\data

\pgfplotsset{colormap/hsv}
\tikzset{%
  sector/.style={
    /utils/exec=\pgfmathparse{int(#1/\nrows*900+50)}%
      \pgfplotscolormapdefinemappedcolor{\pgfmathresult},
    top color=mapped color!75!black,
    bottom color=mapped color,
    shading angle=#1*\step+\step/2-90,
    draw=white,
    very thick
  }
}
\begin{document}

\begin{tikzpicture}

\foreach \i [evaluate={\j=\i+1;}] in {0,...,\nrows}{
  \pgfplotstablegetelem{\i}{language}\of{\data}\let\language=\pgfplotsretval
  \pgfplotstablegetelem{\i}{adjustedradius}\of{\data}\let\years=\pgfplotsretval
  \pgfmathsetmacro\years{\years/2}
  \path [sector=\i] (\i*\step:1) (\i*\step:1+\years) 
    arc (\i*\step:\j*\step:1+\years) -- (\j*\step:1)
    arc (\j*\step:\i*\step:1) -- cycle;
  \pgfmathparse{int(\years>2)}
  \ifnum\pgfmathresult=1
    \node [text=white, font=\bfseries] 
      at (\i*\step+\step/2:1+\years/2) {\language};
  \else
    \node [text=black, font=\bfseries]
      at (\i*\step+\step/2:1+\years+1/2) {\language};
  \fi
}
\end{tikzpicture}
\end{document}
0

The wheelchart package, which I wrote, can be used.

The text is given by the third variable \WCvarC. With the key data=\WCvarC this text is placed in the data but using the key data{1,2,4,10}= the data is empty in the slices 1, 2, 4 and 10.

Similarly, with the key wheel data= the wheel data is empty but using the key wheel data{1,2,4,10}=\WCvarC, the text is placed in the wheel data in the slices 1, 2, 4 and 10.

The gap between the slices is obtained with the key gap=0.02.

The key radius={1}{sqrt(\WCvarA+1^2)} sets the inner radius to 1 and the outer radius to sqrt(\WCvarA+1^2). Hence the area of a slice is proportional to \WCvarA which is the first variable.

The shading is defined in the key slices style.

Furthermore, value=1 so that the angle of each slice is the same.

enter image description here

\documentclass[border=6pt]{standalone}
\usepackage{wheelchart}
\begin{document}
\begin{tikzpicture}
\sffamily
\wheelchart[
  counterclockwise,
  data=\WCvarC,
  data{1,2,4,10}=,
  gap=0.02,
  radius={1}{sqrt(\WCvarA+1^2)},
  slices style={
    bottom color=\WCvarB,
    top color={\WCvarB!80!black},
    shading angle={\WCmidangle-90}
  },
  start angle=0,
  value=1,
  wheel data=,
  wheel data{1,2,4,10}=\WCvarC,
  wheel data style=white
]{%
  5/green/html,
  5/red/css,
  4/cyan/javascript,
  4/magenta/sql,
  3/blue/java,
  2/red/ruby,
  2/green/python,
  2/cyan/{c/c++},
  1/magenta/.net,
  6/blue/perl%
}
\end{tikzpicture}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .