Search code examples
graphgnuplot

Pie chart gnuplot


Does anyone have example code in gnuplot for a pie chart? I can't find any great example with a simple graph and the text around it and in it with the % signs that shows easily how much each part has of the circle.

Some example data:

Management frames   4596
Control frames  70173
Data frames 40347
TCP packets 36864
HTTP packets    525
ICMP packets    47
Total frames    115116

Solution

  • Updated: After some years, I came again across this post, and I thought the code looked pretty messy. Therefore an attempt to improve and clean it up.

    The following code is a bit different from the link I referenced above.

    • instead of a predefined color sequence or number codes in a separate list, the colors of the sections are given in the datablock (or datafile) next to the item/number by the names of predefined colors in gnuplot (see also https://stackoverflow.com/a/55736522/7295599). Because palette is used you can enter either colorname or hex-code, e.g. magenta or 0xff00ff.

    • the labels are aligned left or right depending on their position relative to 0.

    • you can choose the starting angle by PieStart and "rotation"-direction by PieDirection of the pie-chart

    • you can add individual radial and angular offsets for segments and labels

    • as you can see, there is no need for the total sum in the raw data. The total sum will be calculated automatically.

    • the reason why I define various functions f(n) which actually do not depend on n is to get the current values of other variables (at the time of calling the function) instead of passing a lot of parameters to the functions.

    I hope you can adapt this code to your needs.

    Code: (works with gnuplot>=5.0.0)

    ### pie-chart with labels with gnuplot
    reset session
    
    set size square
    set angle degrees
    set border 0
    unset colorbox
    unset tics
    unset key 
    
    $Data <<EOD
    # label     value   color      SRoff   SAoff   LRoff   LAoff
    "Alpha"     85843   red          0       0      0      0
    "Beta"      44000   green        0.2    45      0.2    0
    "Gamma"     25399   blue         0       0      0      0
    "Delta"     18451   magenta      0       0      0      0
    "Epsilon"   12344   yellow       0       0      0      0
    "Zeta"      11999   cyan         0       0      0      0
    "Eta"       9000    orange       0       0      0      0
    "Theta"     8500    0xb0f060     0       0      0.03   0
    "Iota"      4711    dark-violet  0       0      0.12   0
    EOD
    
    colLabel   = 1     # label
    colValue   = 2     # segment value
    colColor   = 3     # segment color, either color name or 0xRRGGBB value
    colSegRoff = 4     # radial  segment offset
    colSegAoff = 5     # angular segment offset
    colLabRoff = 6     # radial  label   offset
    colLabAoff = 7     # angular label   offset
    
    # define a palette from colornames of the datafile/datablock in column colColor
    set table $Dummy
        myPalette = ''
        plot $Data u (myPalette = myPalette.(myPalette eq '' ? '' : ', ').sprintf('%d "%s"',$0,strcol(colColor)),$0) with table
        myPalette = '('.myPalette.')'
    unset table
    set palette defined @myPalette
    
    stats $Data u colValue nooutput    # get total sum from column colValue
    TotalSum = STATS_sum
    
    set xrange[-1.5:1.5]
    set yrange[-1.5:1.5]
    
    PieStart       = 90      # 0 = 3 o'clock, 90 = 12 o'clock
    PieDirection   = -1      # -1 clockwise, 1 counterclockwise
    Radius         = 1.0
    RadiusLabelOff = 0.05    # default radial label offset
    SegPosX(n)     = column(colSegRoff)*cos((a2+a1+column(colSegAoff))*0.5)
    SegPosY(n)     = column(colSegRoff)*sin((a2+a1+column(colSegAoff))*0.5)
    LabPosX(n)     = (Radius+RadiusLabelOff+column(colLabRoff))*cos((a2+a1+column(colLabAoff))*0.5)
    LabPosY(n)     = (Radius+RadiusLabelOff+column(colLabRoff))*sin((a2+a1+column(colLabAoff))*0.5)
    a1=a2=PieStart
    getAngles(n)   = (a1=a2, a2=a2+sgn(PieDirection)*column(colValue)/TotalSum*360)
    getLabel(n)    = sprintf("%s %.1f%%", strcol(colLabel),  column(colValue)/TotalSum*100)
    
    set multiplot layout 2,1
    
        plot $Data u (getAngles(0), SegPosX(0)):(SegPosY(0)):(Radius):(PieDirection<0?a2:a1):(PieDirection<0?a1:a2):($0) \
               with circles fs solid 1.0 lc palette notitle,\
            '' u ( getAngles(0), Align=LabPosX(0)):(LabPosY(0)): (Align>0? getLabel(0) : '') with labels font ",10" left, \
            '' u ( getAngles(0), Align=LabPosX(0)):(LabPosY(0)): (Align<0? getLabel(0) : '') with labels font ",10" right
    
        PieDirection = +1
        a1=a2=PieStart
        replot
    
    unset multiplot
    ### end of code
    

    Result:

    enter image description here