gnuplot: need help plotting both column and row stacks - gnuplot

I have a datafile listing bandwidth for each machine on a network, but down and up. It looks like:
"" 0 1 2 3
"Machine 1 D" 320 768 1287 1318
"Machine 1 U" 119 245 561 491
Where the first column is the data key, and there's 24 columns representing hours of data. I'd like to generate two histograms,(A) a rowstack that shows the total bandwidth of all the machines for each hour, and (B) a columnstack that shows each machine's hourly usage. So, in graph A, the hours would appear on the x axis, and each machine's usage would stack up cumulatively. In graph B, the machine names would appear on the x axis, and the usage during each hour would stack up cumulatively.
And, for extra credit, I'd like to graph the data twice, alternating rows (once for upload, once down). The trick here, is to preserve the first row as it contains column titles.
Does anyone know how to do this? I can get some results, but can't seem to get the key/xtics/titles etc to show correctly.
EDIT: Ok, so here's an example of what I have for a columnstack -
reset
set style fill solid noborder
file = '..\test\example.dat'
col = 24
set style data histogram
set style histogram columnstacked
plot \
for [i=2:col+1] \
file \
u i title columnhead
Which generates something like:
So, for example, how do I create a key with the column(1) fields?

In the end, I discovered a number of things. First, using iteration in gnuplot seems rather buggy - it works, but constrains other options. Second, I reported a bug where the "every" statement is incompatible with using columnheaders. Third, I can't column/rowstack and declare the x axis as a time/date value. That left me basically writing out the plot long-hand.
columnstacked:
set xtics ("midnight" 0, "1a" 1, ...)
plot file u 3:key(1) notitle, '' u 4, ...
rowstacked:
plot file u 3:xtic(1) t "midnight", u 4 t "1a", ...

Related

plotting the total monthly amount of rain from a daily data file with gnuplot

I've got a data file with daily values for the amount of rain in the 4th column, for each day of the year.
I'd like to plot a bar graph with each month in the x-axis, and the total monthly amount of rain in the y-axis: that is, to plot "January" (with %B or %b format) vs the sum of the 31 first values of the 4th column. Then to plot "February" vs the sum of the next 28 values of the 4th column, and so on. Do you know how to do that with gnuplot ? Besides, is it possible to write the numerical value of the monthly amounts of rain, on top of each bar ?
I can imagine and understand that for a gnuplot beginner it will not be easy to find and combine the necessary commands to realize your task. If you do a search you will most probably not find exactly your case, but there should be very similar questions and examples around. The key search would be "creating a histogram".
Check help smooth frequency, help strftime, help strptime, help datablocks, help table, basically for every command or keyword there should be a help entry.
The following example is one way to achieve what you are asking for. It is basically binning data, like creating a histogram. Here, your bins will be the months in the following numerical format, e.g. 202109, 202110, 202111, 202112, 202201, etc.
In the example below, some random test data (mm of rain per day) will be created in order to illustrate the result with a graph.
Example data in $Data:
2021-12-01 66
2021-12-02 0
2021-12-03 0
2021-12-04 17
2021-12-05 52
Plot your data into a datablock $Monthly using the option smooth frequency. It will sum up all values per month.
The result in $Monthly will be something like this:
202107 368
202108 622
202109 557
202110 361
202111 628
I hope you can adapt the code to your data and needs.
Edit: the previous version of the code used the plotting style with boxes for the monthly plot. However, this style is centering the box at the beginning of the month, which is undesired here (especially when plotting together with the daily rain). The modified code is using the plotting style with boxxyerror which plots the boxes from the beginning of the month to the beginning of the next month. Check help boxes and help boxxyerror.
Code:
### sum up monthly rainfall
reset session
TimeFmtInput = "%Y-%m-%d"
# create some random test data
set print $Data
StartDate = strptime(TimeFmtInput,"2021-04-01")
do for [i=0:280] {
RainMM = int(rand(0)+0.3) * rand(0)*100
print sprintf("%s %.0f",strftime(TimeFmtInput,StartDate+3600*24*i),RainMM)
}
set print
set table $Monthly
plot $Data u (tm_year(timecolumn(1,TimeFmtInput))*100+tm_mon(timecolumn(1,TimeFmtInput))+1):2 smooth freq
unset table
set style fill solid 0.3
set format x "%Y\n%b" timedate
set key out top center
set grid x,y
set xtics out
NextMonth(t) = strptime("%Y%m",sprintf("%04d%02d",tm_year(t),tm_mon(t)+2))
NextDay(t) = t + 24*3600
set multiplot layout 2,1
plot $Data u (t0=timecolumn(1,TimeFmtInput)):2:(t0):(NextDay(t0)):(0):2 w boxxy lc "blue" title "Daily rain / mm"
set xrange[GPVAL_X_MIN:GPVAL_X_MAX] # take the same xrange as the previous plot
plot $Monthly u (t0=timecolumn(1,"%Y%m")):2:(t0):(NextMonth(t0)):(0):2 w boxxy lc "blue" title "Monthly rain / mm"
unset multiplot
### end of code
Result:

gnuplot - adding median to plot with errorbars AND logscale'd x-axis

So I have some data files in format
x y ymin ymax
That I'm plotting with yerrorbars.
Now how would I best add a median of the y values to the plot running over the whole range of x?
UPDATE
I'm also plotting the x axis in logscale which seems to prevent using STATS.
Suppose that your data looks like this:
1 8 6 9
2 6 5 7
3 5 4 8
4 6 5 8
We can use the stats command to find the median. The use is similar to the plot command. Here, we only need to do analysis of the second column, so we will only specify the second column:
stats datafile u 2 nooutput
The nooutput option tells the command not to print the results. If we wish to see the full analysis, we simply omit that specification. By default, the stats command stores its results in variables of the form STATS_*. We can use a different prefix if desired. See help stats for more details.
At this point, we have a variable STATS_median that stores the median of the y values (which is 6 for the sample data). We can now add the median to the graph in one of two ways. First we can simply add a plot specification to the existing plot command:
plot datafile u 1:2:3:4 with yerrorbars, STATS_median
or we can add a line with the set arrow command and then plot just the yerrorbars:
set arrow 1 from graph 0, first STATS_median to graph 1, first STATS_median nohead
plot datafile u 1:2:3:4 with yerrorbars
Here we give the x coordinate in graph units which range from 0 (the left side) to 1 (the right side) and the y coordinate in the first coordinate system which corresponds to the y1 axis. Specifying nohead says to not draw an arrow head. The 1 immediately following set arrow tags this arrow as arrow 1 so that we can change or remove it easily later.
Other options are available. See help arrow for more details.

Position xtics between bars

I have a dataset
200 45000
600 260000
2000 680000
18000 2800000
I generated this by processing other data (set like {(x0, y0), (x1, y1),..}). On the first row in the first column is the low quartile of x and in the second column is sum of ys corresponding to data with x_0 < 200. In the second column it is similar but the first column is median and second column is the mentioned sum for 200 < x_0 <= 600. Third is similar (just with high quartile), fourth has the maximum value of x in the first column.
I want to render a box plot similar to the one below but the xtics should be right between the borders of the boxes (so each box would be between two xtics). How can I do that? The manual page for "set xtics" didn't help.
This was generated by this code (few unimportant style settings not shown):
plot 'data/example.dat' using 1:2:xtic(1) with boxes
There is a related question Gnuplot put xtics between bars but I don't think I can apply that since I want my boxes to keep their width (although I need to somehow modify it a bit so that 200 and 600 don't overlap).
You can use the fsteps plotting style. But, with this you need to add an additional line to get the plot right:
0 45000
200 45000
600 260000
2000 680000
18000 2800000
and plot this e.g. with
set xtic rotate
plot 'test.dat' using 1:2:xtic(1) with fsteps lw 3 notitle

gnuplot: time course plot of a matrix of data

I have Matrix Data like:
gnuplot: 3D plot of a matrix of data
How can I plot a 2D time course of parts of the data. E.g. in the example the time course for the value 0.6 would be: -6.35, -6.52, -6.48, -5.91.
Thanks in advance
Basically you have column data and you want to plot the values on one of them, column 3 in the example you give. In gnuplot this is achieved with using:
plot "data" using 0:3 every ::1
using 0:3 means "plot the values in column 0 as the x value and those in column 3 as the y value". Column 0 in gnuplot gives the order in which the data element appears (that is, 1, 2, 3, 4, ...).
every ::1 means start by plotting item number 1 (the first item would be number 0 in gnuplot). In your example this prevents 0.6 to be plotted together with the other elements in the column, -6.35, -6.52, -6.48, -5.91.
Typing help using and help every within gnuplot will give you more detailed info.

Gnuplot - How to place y-values above bars when using Histogram style?

I am currently using a script to generate histogram plots, e.g., by doing:
set style histogram cluster gap 4
plot for [COL=2:10] 'example.dat' u COL:xticlabels(1) title columnheader(COL)
Now I wish to add the y-values (numbers) above the bars in the histogram but adding w labels gives the 'Not enough columns for this style' error.
plot for [COL=2:10] 'example.dat' u COL:xticlabels(1) title columnheader(COL), \
for [COL=2:10] 'example.dat' u COL title '' w labels
Is it possible to add y-labels using the histogram style?
Note: I know that there are examples for plotting with boxes. I wish to make this work with the histogram style if possible.
Here's a test datafile I came up with:
example.dat
hi world foo bar baz qux
1 2 3 4 5 6
4 5 7 3 6 5
Here's the script I used to plot it:
set yrange [0:*]
GAPSIZE=4
set style histogram cluster gap 4
STARTCOL=2 #Start plotting data in this column (2 for your example)
ENDCOL=6 #Last column of data to plot (10 for your example)
NCOL=ENDCOL-STARTCOL+1 #Number of columns we're plotting
BOXWIDTH=1./(GAPSIZE+NCOL) #Width of each box.
plot for [COL=STARTCOL:ENDCOL] 'example.dat' u COL:xtic(1) w histogram title columnheader(COL), \
for [COL=STARTCOL:ENDCOL] 'example.dat' u (column(0)-1+BOXWIDTH*(COL-STARTCOL+GAPSIZE/2+1)-0.5):COL:COL notitle w labels
Each cluster of histograms takes a total width of 1 unit on the x axis. We know how many widths we need (the number of boxes +4 since that is the gapsize). We can calculate the width of each box (1/(N+4)). We then plot the histograms as normal. (Note that I added with histogram to the plot command).
According to the builtin help, labels require 3 columns of data (x y label). In this case, the y position and the label are the same and can be read directly from the column COL. The x position of the first block is centered 0 (and has a total width of 1). So, the first block is going to be located at x=-0.5+2*BOXWIDTH. The 2 here is because the gap is 4 boxwidths -- two on the left and 2 on the right. The next block is going to be located at -0.5+3*BOXWIDTH, etc. In general, (as a function of COL) we can write this as
-0.5+BOXSIZE*(COL-STARTCOL+1+GAPSIZE/2)
We need to shift this to the right by 1 unit for each additional block we read. Since each block corresponds to 1 line in the data file, we can use pseudo-column 0 (i.e. column(0) or $0) for this since it gets incremented for each "record/line" gnuplot reads. The 0th record holds the titles, the first record holds the first block. Since we want a function which returns 0 for the first record, we use column(0)-1. Putting it all together, we find that the x-position is:
(column(0)-1-0.5+BOXSIZE*(COL-STARTCOL+1+GAPSIZE/2))
which is equivalent to what I have above.

Resources