Clustered bar plot in gnuplot with errorbars - gnuplot

I'm new to using gnuplot and I've followed this question which plots the data as I desire. However, I'd very much like to also include error bars. I've tried to do so by adding min and max error columns as follows:
Broswer,Video,min,max,Audio,min,max,Flash,min,max,HTML,min,max,JavaScript,min,max
IE,30%,5,5,10%,5,5,25%,5,5,20%,5,5,15%,5,5
Chrome,20%,5,5,5%,5,5,35%,5,5,30%,5,5,10%,5,5
Which I then try to plot with the script modified as follows:
set terminal pdf enhanced
set output 'bar.pdf'
set style data histogram
set style histogram cluster gap 1
set style fill solid border rgb "black"
set auto x
set yrange [0:*]
set datafile separator ","
plot 'data.dat' using 2:xtic(1) title col with yerrorbars, \
'' using 3:xtic(1) title col with yerrorbars, \
'' using 4:xtic(1) title col with yerrorbars, \
'' using 5:xtic(1) title col with yerrorbars, \
'' using 6:xtic(1) title col with yerrorbars
From what I understand from reading this should also plot errorbars, but I get the error:
"plot2", line 16: Not enough columns for this style
Googling this error informs me that it has something to do with the first column being non-numerical. I've tried a few suggestions including this one, but nothing has worked so far. So, any suggestions? Thanks.

This error tells you, that the yerrorbars plotting style requires more than one column for plotting (the xtic(1) takes a special parts). Looking at the documentation, you can see, that you can use either two, three or four columns. I don't go more into detail, because the with yerrorbars selects a completely new plotting style and you don't get any histogram at all.
In order to plot clustered histograms, you must add errorbars to the histogram's style definition, and of course you must give the column for the yerror values:
set style data histogram
set style histogram cluster gap 1 errorbars
set style fill solid border rgb "black"
set auto x
set yrange [0:*]
set datafile separator ","
plot 'data.dat' using 2:3:xtic(1) title col(2),\
'' using 5:6 title col(5), \
'' using 8:9 title col(8), \
'' using 11:12 title col(11), \
'' using 14:15 title col(14)
Or, in shorter notation
plot for [i=2:14:3] 'data.dat' using i:i+1:xtic(1) title col(i)
If you explicitly need to plot min and max values, than you must add a third column. But then the last two columns are ymin and ymax and not delta values. Judging from you data file error, the values in the data file are deltas, so the plot command should be:
plot for [i=2:14:3] 'data.dat' using i:(column(i) - column(i+1)):(column(i) + column(i+2)):xtic(1) title col(i)

Related

Gnuplot: Violin plot with data from file

I created a script to plot the columns of a dataset using violin plots to show the distribution of the data points starting from the Gnuplot Demo Scripts. However, I can't solve the following error:
"violinplot.gnu", line 27: all points y value undefined!
Does anyone have any idea?
The script:
reset
set terminal pdfcairo size 20,14 enhanced font 'Times,28'
set output 'violinplot.0.pdf'
set datafile separator ','
set table $kdensity1
plot 'profile.csv' using 2:(1) smooth kdensity bandwidth 10. with filledcurves above y lt 9 title 'B'
unset table
unset key
print $kdensity1
set border 2
#unset margins
#unset xtics
set ytics nomirror rangelimited
set title "Distribution of times in milliseconds"
set boxwidth 0.075
set style fill solid bo -1
set errorbars lt black lw 5
set xrange [-6:6]
plot $kdensity1 using (1 + $2/1.):1 with filledcurve x=1 lt 10, \
$kdensity1 using (1 - $2/1.):1 with filledcurve x=1 lt 10
The dataset is in a CSV format as follows (and each column contains time in milliseconds):
1,1814,604,840,1306,13623
2,2195,68,908,1380,14416
3,1173,70,887,512,14301
4,1286,112,982,1541,9549
5,630,97,869,1321,5725
6,1227,689,917,393,4700
7,3402,357,951,500,5431
8,3429,120,969,1661,6281
...
Gnuplot Version 5.2 patchlevel 2
The reason for your error is simple but "nasty" and hidden.
Your input data is comma separated. However, if you plot to a table via set table $kdensity the default column separator is whitespace. That's why gnuplot doesn't find any data in column 2.
I guess since gnuplot 5.2.2. you could set set table $kdensity separator comma. But in order to get a comma as separator you have to use the "plotting style" with table (e.g. plot FILE u 1:2 w table). However, with table and smooth ... do not work together. Either you use with table and you will get the comma but not "smoothed" or you "smooth" and you will not get the comma.
Two possible solutions:
after plotting to the smoothed table set your separator to whitespace (see example below).
or alternatively,
change your input data to whitespace separated.
If you want plot the original (comma separated) data as well, then you have two different column separators. Then you have to apply another workaround.
Script: (works with gnuplot>=5.2.2)
### violin plot with comma separated input data
reset session
# create some random test data (comma separated)
set table $Data separator comma
set samples 100
n = 0
plot for [i=1:3] '+' u (n=n+1):(invnorm(rand(0))*i*25 +i*200) w table
unset table
set datafile separator ','
set table $kdensity
set samples 1000
plot $Data using 2:(1) smooth kdensity bandwidth 10.
unset table
set datafile separator whitespace
set key noautotitle
set style fill solid 0.7
plot $kdensity u (1 + $2/1.):1 w filledcurves x=1 lt 10, \
'' u (1 - $2/1.):1 w filledcurves x=1 lt 10
### end of script
Result:

plotting two histograms, one w/ and one w/o error bars in one plot

I have the below script, which works fine when I have a third column in the second data set. Now I want to get the first histogram being drawn w/ error bars, and the second w/o. I can remove the :3 from the second plot command but gnuplot will complain about not enough data specified for the second histogram. If I remove set style histogram errorbars ... but that would disable the error bars on the first histogram, too. Is there a way to plot two histograms in the same figure, where one doesn't have error bars.
set xlabel ""
set ylabel ""
set boxwidth 0.9 absolute
set style fill solid 1.00 border -1
set style histogram errorbars gap 1
set style data histograms
set yrange [-1.746917959031165368e-01:3.668527713965446857e+00]
unset key
set datafile commentschar "#"
plot '-' using 2:3:xtic(1) title "onehist",\
'-' using 2:3:xtic(1) title "otherhist"
-3.583733737468719482e-01 1.073847990483045578e-02 1.073847990483045578e-02
-3.382162153720855713e-01 2.274234220385551453e-02 1.329828426241874695e-02
2.261839509010314941e-01 2.859487235546112061e-01 8.173441886901855469e-02
e
-1.164875924587249756e-01 4.266476333141326904e-01
-9.633044153451919556e-02 5.953223109245300293e-01
-7.617329061031341553e-02 6.151663661003112793e-01
-5.601614341139793396e-02 9.624376893043518066e-01
e
I'm not sure if it is possible to do this generally, but you can draw your histograms without the errorbars and then add them afterwards with an additional plot command.
plot '-' using 2:xtic(1) title 'onehist',\
'-' using ($0-0.2):2:3 with yerrorbars lc 'black' pt 0, \
'-' using 2:xtic(1) title 'otherhist',\
I'm not entirely sure how to determine the range of the actual bars, so the error bars are not perfectly centered, but this will place them on your graph as requested.
The additional command uses the yerrorbars style (which is how the histogram bars are drawn) to draw the error bars.
However, this isn't the best way to draw histograms. Gnuplot will treat the x-axis as a category with values 0, 1, 2, 3, etc. Therefore, even though you have different x values in both of your lists above, they will become superimposed over each other (and the second plot will change the x-axis values set by the first).
For your example, I would recommend using the boxes and boxerrorbars style.
set style fill solid
set boxwidth 0.01
plot '-' using 1:2:3 with boxerrorbars, '-' u 1:2 with boxes
or if you need the error bars to be a different color, draw them separately
plot '-' using 1:2 with boxes,\
'-' using 1:2:3 with yerrorbars lc 'black' pt 0,\
'-' u 1:2 with boxes

Gnuplot stacked histogram skipping the first bin

I'm trying to use gnuplot to plot a stacked histogram of some data but it skips the first bin (the first row of the data file).
The data is:
1 0.2512 0.0103 0.9679
2 0.4730 0.2432 0.8468
3 0.6669 0.2826 0.6895
4 0.6304 0.2268 0.7424
And the plot code is
set title "Data"
set key invert reverse Left outside
set key autotitle columnheader
set style data histogram
set style histogram rowstacked
set style fill solid border -1
#set boxwidth 0.75
plot 'data.dat' using 2:xtic(1) title 'X', '' using 3 title 'Y', '' using 4 title 'Z'
The output is. I checked it and it correctly displays the data of the 2nd, 3rd and 4th rows of the data file. Why am I missing the first bin..?
Thanks a lot!
I already checked this with no help: Using gnuplot for stacked histograms
As it turns out, it was a very simple mistake, that I've fixed mostly thanks to Azad comment about the titles.
The new code is:
set title "Position error along the three axis"
set key invert reverse Left outside
#set key autotitle columnheader
set style data histogram
set style histogram rowstacked
set style fill solid border -1
#set boxwidth 0.75
plot 'data.dat' using 2:xtic(1), '' using 3, '' using 4
Titles have been removed from the code. Gnuplot was taking the first row (which should have been the first bin) as the titles and then it was overwritten by the title 'X' etc.
The new data looks like this:
0 X Y Z
1 0.2512 0.0103 0.9679
2 0.4730 0.2432 0.8468
3 0.6669 0.2826 0.6895
4 0.6304 0.2268 0.7424
This fixed the problem, now all the bins are correctly displayed!

Gnuplot interchanging Axes

I would like to reproduce this plot with gnuplot:
My data has this format:
Data
1: time
2: price
3: volume
I tried this:
plot file using 1:2 with lines, '' using 1:3 axes x1y2 with impulses
Which gives a normal time series chart with y1 as price and y2 as volume.
Next, I tried:
plot file using 2:1 with lines, '' using 2:3 axes x1y2 with impulses
Which gives prices series with y1 as time and y2 as volume.
However, I need the price to remain at y1 and volume at x2.
Maybe something like:
plot file using 1:2 with lines,' ' using 2:3 axes y1x2 with impulses
However, that does not give what I want.
Gnuplot has no official way to draw this kind of horizontal boxplots. However, you can use the boxxyerrorbars (shorthand boxxy) to achieve this.
As I don't have any test data of your actual example, I generated a data file from a Gaussian random-walk. To generate the data run the following python script:
from numpy import zeros, savetxt, random
N = 500
g = zeros(N)
for i in range(1, N):
g[i] = g[i-1] + random.normal()
savetxt('randomwalk.dat', g, delimiter='\t', fmt='%.3f')
As next thing, I do binning of the 'position data' (which in your case would be the volume data). For this one can use smooth frequency. This computes the sum of the y values for the same x-values. So first I use a proper binning function, which returns the same value for a certain range (x +- binwidth/2). The output data is saved in a file, because for the plotting we must exchange x and y value:
binwidth = 2
hist(x) = floor(x+0.5)/binwidth
set output "| head -n -2 > randomwalk.hist"
set table
plot 'randomwalk.dat' using (hist($1)):(1) smooth frequency
unset table
unset output
Normally one should be able to use set table "randomwalk.hist", but due to a bug, one needs this workaround to filter out the last entry of the table output, see my answer to Why does the 'set table' option in Gnuplot re-write the first entry in the last line?.
Now the actual plotting part is:
unset key
set x2tics
set xtics nomirror
set xlabel 'time step'
set ylabel 'position value'
set x2label 'frequency'
set style fill solid 1.0 border lt -1
set terminal pngcairo
set output 'randwomwalk.png'
plot 'randomwalk.hist' using ($2/2.0):($1*binwidth):($2/2.0):(binwidth/2.0) with boxxy lc rgb '#00cc00' axes x2y1,\
'randomwalk.dat' with lines lc rgb 'black'
which gives the result (with 4.6.3, depends of course on your random data):
So, for your data structure, the following script should work:
reset
binwidth = 2
hist(x) = floor(x+0.5)/binwidth
file = 'data.txt'
histfile = 'pricevolume.hist'
set table histfile
plot file using (hist($2)):($3) smooth unique
unset table
# get the number of records to skip the last one
stats histfile using 1 nooutput
unset key
set x2tics
set xtics nomirror
set xlabel 'time'
set ylabel 'price'
set x2label 'volume'
set style fill solid 1.0 border lt -1
plot histfile using ($2/2.0):($1*binwidth):($2/2.0):(binwidth/2.0) every ::::(STATS_records-2) with boxxy lc rgb '#00cc00' axes x2y1,\
file with lines using 1:2 lc rgb 'black'
Note, that this time the skipping of the last table entry is done by counting all entries with the stats command, and skipping the last one with every (yes, STATS_records-2 is correct, because the point numbering starts at 0). This variant doesn't need any external tool.
I also use smooth unique, which computes the average value of the , instead of the sum (which is done with smooth frequency).

Plotting graph using gnuplot

htmlResponseBytes 39842 397888
cssResponseBytes 109265 108988
imageResponseBytes 205179 206662
javascriptResponseBytes 468573 476888
otherResponseBytes 4326 4378
I want to plot Bar graph this data using gnuplot. 1st column should be present on x-axis, 2nd and 3rd column should be plotted using bar chart. 2nd column should have legend today and 3rd column should have legend yesterday. Also the values should be present on top of each bar.
I have tried this
reset
dx=5.
n=2
total_box_width_relative=0.75
gap_width_relative=0.1
d_width=(gap_width_relative+total_box_width_relative)*dx/2.
reset
set term png truecolor
set output "profit.png"
set xlabel "Year"
set ylabel "Profit(Million Dollars)"
set grid
set boxwidth total_box_width_relative/n relative
set style fill transparent solid 0.5 noborder
plot "profit.dat" u 1:2 w boxes lc rgb"green" notitle,\
"profit.dat" u ($1+d_width):3 w boxes lc rgb"red" notitle
Copied this code from here, works fine for his data file but doesn't work for mine data file pasted at the top
How about this:
set style data histogram
set style histogram cluster gap 1
set xtics rotate by 90
set style fill solid
plot 'test.dat' using 2:xtic(1) lc rgb "blue", \
'' using 3

Resources