Search code examples
plotgnuplot

Show X Axis and align to y axis range in Gnuplot


i'm trying to create a violin plot with some data in gnuplot. The issue i'm facing is that the x axis is not plotted, only xtics are shown, and it also seems that the axis is not aligned with the bottom of the y range. I tried to play with xtics command and with set zeroaxis but I wasn't able to solve the issue.

The code I'm using is the following:

set terminal svg size 1920,1080
set output "pic.svg"

set print $viol0
        y = 0.24
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.48
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.28
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.56
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.52
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.32
            print sprintf(" 0.0 %8.5g", y)
            
        unset print
set print $viol1
        y = -0.24
            print sprintf(" 0.0 %8.5g", y)
            
        y = -0.16
            print sprintf(" 0.0 %8.5g", y)
            
        y = -0.44
            print sprintf(" 0.0 %8.5g", y)
            
        y = -0.28
            print sprintf(" 0.0 %8.5g", y)
            
        y = -0.28
            print sprintf(" 0.0 %8.5g", y)
            
        y = -0.56
            print sprintf(" 0.0 %8.5g", y)
            
        unset print
set print $viol2
        y = 0.0
            print sprintf(" 0.0 %8.5g", y)
            
        y = 1.0
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.5833333333333344
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.5000000000000009
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.7499999999999996
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.08333333333333348
            print sprintf(" 0.0 %8.5g", y)
            
        unset print
set print $viol3
        y = 0.3333333333333336
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.5999999999999998
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.5999999999999998
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.6666666666666664
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.6999999999999997
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.5666666666666671
            print sprintf(" 0.0 %8.5g", y)
            
        unset print
set print $viol4
        y = 1.2999999999999996
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.8499999999999999
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.975
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.7999999999999999
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.8499999999999999
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.7749999999999999
            print sprintf(" 0.0 %8.5g", y)
            
        unset print
set print $viol5
        y = 2.8666666666666694
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.6000000000000024
            print sprintf(" 0.0 %8.5g", y)
            
        y = 1.0666666666666682
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.9333333333333347
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.8666666666666665
            print sprintf(" 0.0 %8.5g", y)
            
        y = 0.733333333333333
            print sprintf(" 0.0 %8.5g", y)
            
        unset print
set title 'Overview'

set border 2
set xrange [33:36]
set xtics ("A" 34, "B" 35)
set xtics nomirror scale 0
set ytics nomirror rangelimited
unset key
set style data points

set linetype  9 lc "#800072b2" ps 0.5 pt 5
set linetype 10 lc "#8033bbbb" ps 0.5 pt 5


# set title "Same data - kernel density"
set style data filledcurves below
set auto x
unset ytics
set border 3
set margins screen .15, screen .85, screen .15, screen .85
set key

set table $kdensity0
plot $viol0 using 2:(1) smooth kdensity bandwidth 0.15 with filledcurves above y lt 9
unset table
set table $kdensity1
plot $viol1 using 2:(1) smooth kdensity bandwidth 0.15 with filledcurves above y lt 9
unset table
set table $kdensity2
plot $viol2 using 2:(1) smooth kdensity bandwidth 0.15 with filledcurves above y lt 9
unset table
set table $kdensity3
plot $viol3 using 2:(1) smooth kdensity bandwidth 0.15 with filledcurves above y lt 9
unset table
set table $kdensity4
plot $viol4 using 2:(1) smooth kdensity bandwidth 0.15 with filledcurves above y lt 9
unset table
set table $kdensity5
plot $viol5 using 2:(1) smooth kdensity bandwidth 0.15 with filledcurves above y lt 9
unset table
unset key

set border 2
unset margins
set ytics nomirror rangelimited

set style boxplot nooutliers
set style fill solid bo -1
set boxwidth 0.075
set errorbars lt black lw 1

set xrange [-0.5 :(6-0.5)]
set xtics autofreq 1
set yrange [-1:2]

plot \
     $kdensity0 using (0 + $2/200.):1 with filledcurve above x=0 lt 9,\
     '' using (0 - $2/200.):1 with filledcurve below x=0 lt 9,\
     $viol0 using (0):2 with boxplot fc "white" lw 2,\
     $kdensity1 using (1 + $2/200.):1 with filledcurve above x=1 lt 9,\
     '' using (1 - $2/200.):1 with filledcurve below x=1 lt 9,\
     $viol1 using (1):2 with boxplot fc "white" lw 2,\
     $kdensity2 using (2 + $2/200.):1 with filledcurve above x=2 lt 9,\
     '' using (2 - $2/200.):1 with filledcurve below x=2 lt 9,\
     $viol2 using (2):2 with boxplot fc "white" lw 2,\
     $kdensity3 using (3 + $2/200.):1 with filledcurve above x=3 lt 9,\
     '' using (3 - $2/200.):1 with filledcurve below x=3 lt 9,\
     $viol3 using (3):2 with boxplot fc "white" lw 2,\
     $kdensity4 using (4 + $2/200.):1 with filledcurve above x=4 lt 9,\
     '' using (4 - $2/200.):1 with filledcurve below x=4 lt 9,\
     $viol4 using (4):2 with boxplot fc "white" lw 2,\
     $kdensity5 using (5 + $2/200.):1 with filledcurve above x=5 lt 9,\
     '' using (5 - $2/200.):1 with filledcurve below x=5 lt 9,\
     $viol5 using (5):2 with boxplot fc "white" lw 2

And this is the result:

enter image description here


Solution

  • It looks like you copied from different gnuplot script examples without knowing what the commands are doing. Well, you have to start somewhere. For every command there should be a help entry. In gnuplot console, simply type help <yourKeyword> and you will get more information.

    A few answers to your questions and comments to your script:

    • x-axis is not plotted because you told gnuplot to do so (set border 2). Check help border

    • y-axis "gap" because you told gnuplot to do so (set ytics rangelimited). Check help ytics.

    • your way to create a datablock looks horribly complicated to me. Maybe, there is a reason for it, but compare with the script below.

    • if your are plotting to a table (the fillstyle and color doesn't matter). And setting a new table will unset the previous one.

    • in your case the violin plot is covered by the boxplot. So, simply introduce a scaling factor to scale the width of your violin plot.

    • you can shorten some commands or keywords using vs. u, with vs. w to make your script shorter and increase readability.

    Check the minimized script below. It certainly has room for further improvements.

    Script:

    ### violin and box plot
    reset session
    
    $viol0 <<EOD
    0.24
    0.48
    0.28
    0.56
    0.52
    0.32
    EOD
    
    $viol1 <<EOD
    -0.24
    -0.16
    -0.44
    -0.28
    -0.28
    -0.56
    EOD
    
    $viol2 <<EOD
    0.0
    1.0
    0.5833333333333344
    0.5000000000000009
    0.7499999999999996
    0.08333333333333348
    EOD
    
    $viol3 <<EOD
    0.3333333333333336
    0.5999999999999998
    0.5999999999999998
    0.6666666666666664
    0.6999999999999997
    0.5666666666666671
    EOD
    
    $viol4 <<EOD
    1.2999999999999996
    0.8499999999999999
    0.975
    0.7999999999999999
    0.8499999999999999
    0.7749999999999999
    EOD
    
    $viol5 <<EOD
    2.8666666666666694
    0.6000000000000024
    1.0666666666666682
    0.9333333333333347
    0.8666666666666665
    0.733333333333333
    EOD
    
    set table $kdensity0
        plot $viol0 u 1:(1) smooth kdensity bandwidth 0.15
    set table $kdensity1
        plot $viol1 u 1:(1) smooth kdensity bandwidth 0.15
    set table $kdensity2
        plot $viol2 u 1:(1) smooth kdensity bandwidth 0.15
    set table $kdensity3
        plot $viol3 u 1:(1) smooth kdensity bandwidth 0.15
    set table $kdensity4
        plot $viol4 u 1:(1) smooth kdensity bandwidth 0.15
    set table $kdensity5
        plot $viol5 u 1:(1) smooth kdensity bandwidth 0.15
    unset table
    
    set title 'Overview'
    set border 3
    unset key
    set linetype  9 lc "#800072b2" ps 0.5 pt 5
    set linetype 10 lc "#8033bbbb" ps 0.5 pt 5
    set style boxplot nooutliers
    set style fill solid border -1
    set boxwidth 0.075
    set errorbars lt black lw 1
    
    set xrange [-0.5 :(6-0.5)]
    set xtics nomirror
    set yrange [-1:2]
    set ytics nomirror # rangelimited
    
    W = 0.025   # scaling factor for violin width
    
    plot \
         $kdensity0 u (0 + $2*W):1 w filledcurve above x=0 lt 9,\
                 '' u (0 - $2*W):1 w filledcurve below x=0 lt 9,\
             $viol0 u (0):1 w boxplot fc "white" lw 2,\
         $kdensity1 u (1 + $2*W):1 w filledcurve above x=1 lt 9,\
                 '' u (1 - $2*W):1 w filledcurve below x=1 lt 9,\
             $viol1 u (1):1 w boxplot fc "white" lw 2,\
         $kdensity2 u (2 + $2*W):1 w filledcurve above x=2 lt 9,\
                 '' u (2 - $2*W):1 w filledcurve below x=2 lt 9,\
             $viol2 u (2):1 w boxplot fc "white" lw 2,\
         $kdensity3 u (3 + $2*W):1 w filledcurve above x=3 lt 9,\
                 '' u (3 - $2*W):1 w filledcurve below x=3 lt 9,\
             $viol3 u (3):1 w boxplot fc "white" lw 2,\
         $kdensity4 u (4 + $2*W):1 w filledcurve above x=4 lt 9,\
                 '' u (4 - $2*W):1 w filledcurve below x=4 lt 9,\
             $viol4 u (4):1 w boxplot fc "white" lw 2,\
         $kdensity5 u (5 + $2*W):1 w filledcurve above x=5 lt 9,\
                 '' u (5 - $2*W):1 w filledcurve below x=5 lt 9,\
             $viol5 u (5):1 w boxplot fc "white" lw 2
    ### end of script
    

    Result:

    enter image description here

    Addition:

    Here is a version where you have your input data all in one datablock (or file) but in different columns. Then you can use a loop for all columns. If you plot your kdensity into a table using a for-loop, you will get different sub-blocks which are separated by two empty lines. If you want to plot that data you can address the sub-blocks via index (check help index).

    Script:

    ### violin plots with a loop
    reset session
    
    $Data <<EOD
    # viol0   viol1   viol2   viol3   viol4   viol5
    0.24    -0.24   0.0     0.333   1.299   2.866
    0.48    -0.16   1.0     0.599   0.849   0.600
    0.28    -0.44   0.583   0.599   0.975   1.066
    0.56    -0.28   0.500   0.666   0.799   0.933
    0.52    -0.28   0.749   0.699   0.849   0.866
    0.32    -0.56   0.083   0.566   0.774   0.733
    EOD
    
    set table $kdensity
        plot for [i=0:5] $Data u i+1:(1) smooth kdensity bandwidth 0.15
    unset table
    
    set title 'Overview'
    set border 3
    unset key
    set linetype  9 lc "#800072b2" ps 0.5 pt 5
    set style boxplot nooutliers
    set style fill solid border -1
    set boxwidth 0.075
    set errorbars lt black lw 1
    
    set xrange [-0.5 :(6-0.5)]
    set xtics nomirror
    set yrange [-1:2]
    set ytics nomirror
    
    W = 0.025   # scaling factor for violin width
    
    plot for [i=0:5] $kdensity index i u (i + $2*W):1 w filledcurves x=i lt 9,\
         for [i=0:5]        '' index i u (i - $2*W):1 w filledcurves x=i lt 9,\
         for [i=0:5]     $Data         u (i):i+1 w boxplot fc "white" lw 2
    ### end of script
    

    Result:

    Although the result should be the same as the graph above, I don't understand yet why the violin plot looks different (in this one not all violin-plots are cut in y-direction). Maybe somebody else can explain.

    enter image description here