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
Related
Normally the xrange and yrange are adjusted to fit the largest and smallest value in the datafile, when plotting according to
plot "my_file.dat" u 1:2
Suppose I want to apply a cutoff to the y-values, so that I only include the points whose y-value is larger than, say 1. If I do
plot "my_file.dat" u 1:($2>1?$2:NaN)
I indeed select only those points. The problem, however, is that the xrange is still adjusted to the range of column 1 of the entire datafile, rather than to only those points which are actually plotted. How can I fix this? My gnuplot version is 5.2.
You also have to filter the undesired x-values in a similar way:
plot 'my_file.dat' u ($2 > 1 ? $1 : NaN):($2 > 1 ? $2: NaN)
If you want to draw a line between these points, a different way of filtering is necessary: see Plotting lines with missing datapoints for multidimensional data
I have a file statistics.dat with measurements I made. It has the format
node Mean StdDev
1 11862.4 142.871
2 11722.4 141.330
[...]
I can make a sorted graph with plot '< sort -n -k2 statistics.dat' u 2
Now I want to add error bars to my plot. When I use plot 'statistics.dat' u 1:2:3 w errorbars The sorting is obviously lost since gnuplot uses the x- and y-value as coordinates.
Is there a way to plot a sorted graph with errorbars?
Or do I need to sort my data and add new x-values according to the sorded position?
Reading the x coordinate from column 1 is counter-productive in this case. To use the ordering of the sorted file, use column 0 (line number):
plot '< sort -n -k2 statistics.dat' u 0:2:3 w errorbars
Depending on the nature of your data and what you are trying to show in the plot, it may be better to simply use the mean value in column 2 as the x coordinate (no extra sorting required):
plot 'statistics.dat' using 2:2:3 with errorbars
If the original file order has some intrinsic significance you might also want to encode the original order somehow, possibly as x tic labels, possibly as a color range:
plot 'statistics.dat' using 2:2:3:1 with errorbars lc palette
I have non-contiguous date/time data (eg weekend data are missing - I don't have rows in data file for them) and I'd like to not to draw them. Graphically, it would be like cutting out a vertical slice of a plot. I'm aware that the X scale would not be linear and am perfectly happy with this.
Here it is what I want to get rid of:
The gnuplot script is auto-generated so it doesn't have to be very neat if it can't be. Currently I'm doing:
set xdata time
set timefmt "%d/%m/%Y-%H:%M:%S"
unset mx2tics
unset mxtics
set xtics border in scale 1,0.5 nomirror rotate font "Times-Roman,12" "$time_min", $xtics, "$time_max"
set xrange ["$time_minb" : "$time_maxb"]
set grid xtics back
Where obviously $var is a proper value of some variable $var. What I'd like to retain: some small (1-2 candles) margin on the left and on the right (between box border and data), labeled ticks every 10 candles.
Ideally all ticks at the borders of time intervals that would be put together in X axis would be marked. Also in the perfect world those labels would be slightly drawn aside to not to overlap each other. But I'm not very picky, I could bear even overlapping of the 2 labels on the joint of 2 intervals if only "empty piece" of a plot is removed.
BTW: I have gnuplot 4.6 but can update to 5.0 if it's necessary.
As I understand the question, it is not about breaking the axis. This would also be possible but might get complicated if you have more than one break.
Actually, there are later questions about the similar topic, e.g.: Remove weekend gaps in gnuplot for candlestick chart
The basic idea is to plot the data against the row index (pseudocolumn 0) instead of time (column 1) in order to make discontinuous data "continuous" and "manually" add the xtic labels.
The accepted solution to the above question, however, is using xticlabels and defines a function which shows, e.g. every 5th xticlabel. This looks OK for the illustrated case. However, although, only every Nth ticlabel will be shown, a tic will be created nevertheless at every data entry which will not look good for data with larger time range.
Hence, another approach would be plotting the data twice: first time for the data and the second time plotting NaN, i.e. nothing but the tics, where you can easily select the spacing via every (check help every). Although the data looks continuous, it might useful to indicate the breaks somehow, e.g. with extra tics or vertical lines. Alternatively, depending on the data, each start of a "continuous" subset could be marked with a date label followed by regular minor tics without labels.
Script: (works with gnuplot>=5.2.0, with some adaptions probably with earlier versions).
### plot dis-continuous time "continuous"
reset session
# create some random test data
set table $Data
myTimeFmt = "%Y-%m-%d"
t0 = time(0)
y0 = 100
f(t) = strftime(myTimeFmt,t1=t0+$0*3600*24)
plot '+' u (f(0)):(y0=y0+rand(0)*2-1) w table
t0 = t1 + (rand(0)*30+30)*3600*24
replot
t0 = t1 + (rand(0)*50+50)*3600*24
replot
unset table
set format x "%Y\n%m-%d" timedate
set grid x,y
set ytics 2
set key noautotitle
set multiplot layout 2,1
plot $Data u (timecolumn(1,myTimeFmt)):2 w l lc "red"
myXTic(col) = strftime("%Y\n%m-%d",timecolumn(col,myTimeFmt))
N = 30
plot $Data u 0:2 w l lc "web-green", \
'' u ($0*N):(NaN):xtic(myXTic(1)) every N
unset multiplot
### end of script
Result:
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.
Can I get gnuplot to display the exact y-value or height of a data point (plotted using "with boxes") over its bar? I would like the plot to be easy to read so nobody has to line up the top of a bar with the y-axis and guess what the value is.
You can use the labels style and combine it into the plot command with the boxes style. The labels style expects 3 columns of data - the x coordinate, the y coordinate, and the actual label text.
For example, with the following data
1 4
2 6
3 2
4 8
the command (we set the yrange to 0 - 10 and boxwidth to 0.9 and set a solid fill style)
plot datafile u 1:2 with boxes, "" u 1:2:2 with labels offset char 0,1
produces
Normally, the labels would be centered on the specified point (the top edge of the box). By specifying an offset, we can move them up to just above the box. Here we used no offset in the x direction, but a unit of 1 in the y direction. We used the character coordinate system, so this corresponds to moving up by one character unit.
I can only think of putting the values where you want them "manually" like this:
set label "value" at 12,34
The numbers are coordinates according to your x and y ranges.
An automatic way would use "with labels", see e.g.
http://gnuplot.sourceforge.net/demo_4.4/stringvar.html