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.
Related
I have a csv file with multiple XY data pairs. Each data pair is separated by one hour. I would like to graph these data pairs in one 3D graph so I can leverage the depth to better visualize the graph. can I set an arbitrary Z value for each XY data pair, where Z=hours?
I understand I could alter the CSV file to have a third column for each pair, but in my case it would be faster to simply arbitrate a z value for each pair (if possible). Thank you.
For example, 1:2 is hour 1, and 3:4 is hour 2, and so on...
Gnuplot treats treats the row number as column 0, so a commands
set datafile separator comma
splot "data.csv" using 1:2:0
would use the first two entries on each line as an x,y pair and assign the row number as z. If by "arbitrary" you mean "some constant I pick beforehand", then you can place that value inside parentheses to indicate it is a numerical value rather than a column number:
FOO = 123.456
splot "data.csv" using 1:2:(FOO)
I have a data file containing z values (m x n = 2068 x 100), but I fail to find a way to make a surface plot in gnuplot out of that.
In MATLAB the command is straight forward: just surf(M).
The values correspond to readouts over time from a spectrometer, i.e.
wavelength scan1 scan2 scan3 scan4
772.7 3.9609 3.9623 3.9593 3.9643
772.8 2.4688 2.4749 2.4669 2.4689
772.9 2.7233 2.7250 2.7240 2.7270
I understand that gnuplot expects the data to be presented in x,y,z fashion, but my data does not provide that. I'm sorry that I can find no other way to describe what I'm after...
Essentially: the x values are in the first row, but the y values should be the index of the column if that makes sense.
Any help would be much appreciated.
Your data format is halfway between the two formats gnuplot knows about. splot $DATA matrix treats all values as z values (no x or y specified). splot $DATA matrix nonuniform expects the first column to contain y values and the first row to contain x values. You have one column of coordinate data but not one row of coordinate data.
It looks like your x values are evenly spaced, so it would produce a valid surface to ignore them:
splot 'matrix.dat' matrix skip 1 every 1::1
matrix tells gnuplot it is an array of z values
skip 1 tells it to skip the first row, which contains labels rather than z
every 1::1 tells it to read every column starting with column 1 (i.e. skip column 0)
However a much better approach is to draw a separate line for each scan rather than trying to treat it as a surface:
set ylabel "Scan" offset 5
set xlabel "Wavelength" offset 0,-2
set xtics .1 offset 0,-1
unset ytics
unset ztics
splot for [col=2:*] 'matrix.dat' using 1:(col):col title columnhead
This thread here:
Custom string in xticlabels
solved the question of customizing xticlabel strings.
Now, how do I sort the data from column 4 (for example) so that only rows containing certain strings in column 4 will be used to create the xticlabel? IOW, what is the proper format to do: (IF strcol(4) eq "Sunrise") plot 'datafile' u 4:2:( xticlabels( strcol(4).strcol(2) ) )
Given this datafile:
Sunrise cat 1
Sunset dog 2
Sunrise fish 3
waste space 4
blah blah 5
Sunrise label 6
we can plot it with this line:
plot 'test.dat' u 3:xticlabels(strcol(1) eq 'Sunrise'?strcol(1).strcol(2):'')
And it creates this plot:
Basically what I did there is I looked at the string in column 1, if it is "Sunrise", I concatenated it with the string in column 2. If it isn't "Sunrise", then I return an empty string to prevent a label from being placed there. This does however, place a major tic at the location of each data point. To avoid that, you can use the following:
plot 'test.dat' u 3:xticlabels(strcol(1) eq 'Sunrise'?strcol(1).strcol(2):NaN)
which produces this plot (I've tested on gnuplot 4.4.2 and 4.6.0):
It also issues a bunch of warnings about non-string labels, but I guess that's OK.
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.
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", ...