RAVI507
RAVI507

Reputation: 129

Generation of pie chart using gnuplot

I have a CSV file with data like:

name,age
raju,23
anju,34
manju,56
sanju,56

I'm trying to generate a pie chart using gnuplot. Here's the command I'm executing:

#!/usr/bin/gnuplot -persist
reset
set terminal wxt
unset key
set datafile separator ","
set xlabel "USERS"
set ylabel "AGE"

plot 'file.csv' using ($0):2:($0):xticlabels(1) with circles lc variable notitle

What am I doing wrong?

Upvotes: 10

Views: 15144

Answers (2)

Ben Aveling
Ben Aveling

Reputation: 924

Another way to get a similar result is to pre-process the data.

e.g., given

raju,23
anju,34
manju,56
sanju,56

We can then calculate, either by hand, or using a script, or using a spreadsheet, the following

23 / ( 23+34+56+56) * 360
=48.9940828402367
34 / ( 23+34+56+56) * 360
=72.4260355029586
56 / ( 23+34+56+56) * 360
=119.289940828402

and

48.9940828402367 +72.4260355029586
=121.420118343195
121.420118343195+119.289940828402
=240.710059171597
240.710059171597 +119.289940828402
=359.999999999999

We now create a data file that looks like

raju,0,48.9940828402367,1
anju,48.9940828402367,121.420118343195,2
manju,121.420118343195,240.710059171597,3
sanju,240.710059171597,360,4

And we can plot that, for e.g., as follows

set style fill transparent solid 0.9 noborder
plot 'test.csv' using (0):(0):(1):2:3:4 with circles lc var notitle

a pie chart, just 4 blocks of colour, no lables

Notes:

  1. There's no code for labels here, I assume you already know how to add those.
  2. Gnuplot always plots circles as circles, regardless of the ratio between x and y axes.

Upvotes: 0

vagoberto
vagoberto

Reputation: 2442

Apparently, Gnuplot does not support pie charts yet; but we can draw it by hand.

First, we need to obtain the angles and percentages related to the second column in your datafile:

set datafile separator ','
stats 'file.csv' u 2 noout      # get STATS_sum (sum of column 2)

ang(x)=x*360.0/STATS_sum        # get angle (grades)
perc(x)=x*100.0/STATS_sum       # get percentage

Then configure the canvas:

set size square                 # square canvas
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1

unset border
unset tics
unset key

and draw the pie chart:

Ai = 0.0; Bi = 0.0;             # init angle
mid = 0.0;                      # mid angle
i = 0; j = 0;                   # color
yi  = 0.0; yi2 = 0.0;           # label position

plot 'file.csv' u (0):(0):(1):(Ai):(Ai=Ai+ang($2)):(i=i+1) with circle linecolor var,\
     'file.csv' u (1.5):(yi=yi+0.5/STATS_records):($1) w labels,\
     'file.csv' u (1.3):(yi2=yi2+0.5/STATS_records):(j=j+1) w p pt 5 ps 2 linecolor var,\
     'file.csv' u (mid=Bi+ang($2)*pi/360.0, Bi=2.0*mid-Bi, 0.5*cos(mid)):(0.5*sin(mid)):(sprintf('%.0f (%.1f\%)', $2, perc($2))) w labels

The first line in the plot command draws the pie chart, where the columns (0):(0):(1):(Ai):(Ai=Ai+ang($2)):(i=i+1) are:

  • columns 1-2: x and y coordinates of the center of the disk
  • column 3: radius of the disk
  • column 4-5: begin and end angles of the region
  • column 6: color of the region

The second and third lines in the plot command place the labels, and the last line puts the percentages in the middle of each region.

The result: Pie chart in Gnuplot

References: (1) Gnuplot surprising (2) Gnuplot tricks


EDIT:

Based on two related questions (this and this), a new script is proposed:

filename = 'test.csv'

rowi = 1
rowf = 7

# obtain sum(column(2)) from rows `rowi` to `rowf`
set datafile separator ','
stats filename u 2 every ::rowi::rowf noout prefix "A"

# rowf should not be greater than length of file
rowf = (rowf-rowi > A_records - 1 ? A_records + rowi - 1 : rowf)

angle(x)=x*360/A_sum
percentage(x)=x*100/A_sum

# circumference dimensions for pie-chart
centerX=0
centerY=0
radius=1

# label positions
yposmin = 0.0
yposmax = 0.95*radius
xpos = 1.5*radius
ypos(i) = yposmax - i*(yposmax-yposmin)/(1.0*rowf-rowi)

#-------------------------------------------------------------------
# now we can configure the canvas
set style fill solid 1     # filled pie-chart
unset key                  # no automatic labels
unset tics                 # remove tics
unset border               # remove borders; if some label is missing, comment to see what is happening

set size ratio -1              # equal scale length
set xrange [-radius:2*radius]  # [-1:2] leaves space for labels
set yrange [-radius:radius]    # [-1:1]

#-------------------------------------------------------------------
pos = 0             # init angle
colour = 0          # init colour

# 1st line: plot pie-chart
# 2nd line: draw colored boxes at (xpos):(ypos)
# 3rd line: place labels at (xpos+offset):(ypos)
plot filename u (centerX):(centerY):(radius):(pos):(pos=pos+angle($2)):(colour=colour+1) every ::rowi::rowf w circle lc var,\
     for [i=0:rowf-rowi] '+' u (xpos):(ypos(i)) w p pt 5 ps 4 lc i+1,\
     for [i=0:rowf-rowi] filename u (xpos):(ypos(i)):(sprintf('%05.2f%% %s', percentage($2), stringcolumn(1))) every ::i+rowi::i+rowi w labels left offset 3,0

This new code results in: new plot

Upvotes: 16

Related Questions