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:
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:
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.