Reputation: 129
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
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
Notes:
Upvotes: 0
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:
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.
References: (1) Gnuplot surprising (2) Gnuplot tricks
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
Upvotes: 16