gnuplot: Points overlap in pm3d with a wide xrange - plot

I'm using gnuplot to plot three dimentions of data using pm3d. I'm trying to plot the number of times an event occurs (z value) with respect to the day of the year (x value) and hour of the day (y value).
Using pm3d works great for up to a range of 600 (rought 2 years of data). However, the points begin to overlap each other when a wider range is required.
I believe this is related to the fact that gnuplot isn't stretching the plot to the full size specified in set terminal. I haven't however been able to find a setting that controls this directly.
the script I'm using:
set terminal png size 10000, 1000
set output "%s_plot.png"
set title "%s's"
set ytics 1,1
set xtics 1
set xrange[0:%s]
set yrange[0:23]
set cbrange[0:%s]
set pm3d map
set palette defined (0 "white", 1 "blue", 31 "red")
splot '%s.data'
aspect of the plot for a range of [0:1000] in x:
aspect of the plot for a range of [0,100] in x:
(the images above are just snippets of the whole thing)
What can I do to remedy this? Perhaps the solution is manually setting the points (squares) to have a fixed width.
Thanks.

For the kind of plot that you want, I would replace your last line with:
plot '%s.data' matrix with image

Related

gnuplot: how to set the size of the points according to the grid

I have the following 'data.dat' file:
# x y z radius
-1.64905083 -1.14142799 -2657.88232 177.358566
-449.735321 416.586914 -2865.25366 10.0000000
178.955292 -256.291138 -2856.96069 89.9588394
-336.942322 184.932343 -2839.22876 90.6131058
-443.635315 -80.0183029 -2863.29077 70.7404404
236.385406 349.893188 -2901.33984 10.0000000
485.313416 -366.513947 -2868.35083 10.0000000
with the positions of the spheres and their radii.
My file.p reads:
set terminal png size 500,500
set output 'file.png'
set multiplot
set xrange [-1000:1000]
set yrange [-1000:1000]
set zrange [-3000:-2500]
splot "data.dat" using 1:2:3:4 ps variable pt 7
splot -(3000**2-x**2-y**2)**(0.5)
but the dots that gnuplot provides me are much bigger.
I understand that it is because ps yields points that are radius times bigger than the normal size.
Meaning that ps does not allow to set the radius of the dots, but rather how many times bigger it is than the normal points.
How can I set the radius of the points please ?
Use "with circles" rather than "with points pt 7".
From the manual:
gnuplot> help with circles
The `circles` style plots a circle with an explicit radius at each data point.
The radius is always interpreted in the units of the plot's horizontal axis
(x or x2). The scale on y and the aspect ratio of the plot are both ignored.
If the radius is not given in a separate column for each point it is taken from
`set style circle`. In this case the radius may use graph or screen coordinates.
Many combinations of per-point and previously set properties are possible.
For 2D plots these include
using x:y
using x:y:radius
using x:y:color
using x:y:radius:color
using x:y:radius:arc_begin:arc_end
using x:y:radius:arc_begin:arc_end:color
By default a full circle will be drawn. It is possible to instead plot arc
segments by specifying a start and end angle (in degrees) in columns 4 and 5.
A per-circle color may be provided in the last column of the using specifier.
In this case the plot command must include a corresponding variable color
term such as `lc variable` or `fillcolor rgb variable`.

how histogram in Gnuplot works

I try to reproduce a simple histogram with Gnuplot with the simple macro:
reset
n=9 #number of intervals
width=1 #interval width
hist(x,width)=width*floor(x/width)
set terminal pngcairo size 800,500 enhanced font 'Verdana,14'
set output "test.png"
set boxwidth width
set style fill transparent solid 0.5 border #fillstyle
set xrange [*:*]
set yrange [0:2.]
set xlabel "x"
set ylabel "Freq."
plot "const.dat" u (hist($1,width)) smooth freq w boxes lc rgb "orange" notitle
whit the follow data:
1.1
1.1
1.1
1.1
1.1
1.1
1.1
1.1
Now I like to understand how the hist(x,width) works in the sense:
hist(x,width)=width*floor(x/width)
works with every numbers taking the width=1 and then:
hist(1.1,1)=1*floor(1.1/1)=1
and so on, right?
Now (hist($1,width)) take all the elements in the columns and applay the hist function to everyone.
And I can be able to make the follow plot with the macro above:!
Question:
If I use (hist($1,width)):(1.0) I Don't understand whit the plots change as all the elements stay in one single boxes (from 0.5 to 1.5) ?
In the first case you specify only a single column in the using statement. Since you need at least two (x and y-value), the specified value (your hist(...)) is used as y-value and the row number as x-value. The statement smooth frequency works such, that it takes all points with the same x-value and sums up the corresponding y-values. In your first example you have no equal x-values since the row number is used.
In the second example, you use the hist(...) value as x-value, which is 1 for all rows. The y-value is 1.0. So you get a single box at x=1 and y=8 (the number of rows).

Plotting an IR Spectrum with Gnuplot

I have an infrared spectrum for a compound of interest that I would like to plot, and I have a spectrum.dat file with all of the data points. It is of the form:
# X Y
300 100
301 100
302 99
303 70
...
3999 98
4000 100
I would like to plot this using an x axis typical of IR spectra, but I am having trouble doing so. If you are unfamiliar, this is what a typical IR spectrum might look like (aside from the labels on the graph itself). Notice that the x-axis is reversed, and that it abruptly doubles its scaling above 2000 units (reciprocal centimeters). Is there a way to coerce Gnuplot into plotting my data this way? I so far have managed to come up with the following script:
# Make an SVG of size 800x500
set terminal svg size 800,500 fname 'CMU Sans Serif' fsize '10'
set output 'ir.svg'
# Color definitions
set border linewidth 1.5
set style line 1 lc rgb '#a0a0a0' lt 1 lw 2 pt 7 # gray
# Format graph
unset key
set xlabel 'Wavenumbers'
set ylabel 'Transmittance'
set xrange [4000:300]
# Plot data
plot 'spectrum.dat' with lines ls 1
This reverses the x-axis nicely, but I can't figure out how to change the scaling in such an unusual way.
As a chemist I am motivated to answer...
As far as I know gnuplot doesn't easily allow for arbitrary axis scaling (unless anyone has bright ideas about how to use set link). My strategy in this kind of situation is to plot the two halves separately and have them join seamlessly:
#!/usr/bin/env gnuplot
set terminal png size 800,500
set output 'ir.png'
set xlabel 'Wavenumbers' offset 20
set ylabel 'Transmittance'
set tics out nomirror
set key bottom right
set bmargin 4
set yrange [0:1]
set multiplot layout 1,2 title 'IR Spectrum of Cholesterol'
# left half of plot
set xrange [4000:2000]
set rmargin 0
set border 7
plot 'cholesterol.txt' notitle
# right half of plot
set xrange [1999:300]
set lmargin 0
set rmargin 2
set border 13
unset xlabel
unset ylabel
unset ytics
plot 'cholesterol.txt' title 'Cholesterol'
unset multiplot
My one quibble is that the 2000 is written twice and looks bolder on my screen, but I will leave fidgeting with the tics to you.
andyras' answer is a nice one, this is an arguably simpler (more elegant :-P) solution in terms of layout options. This should also be a more universal solution. If there are not too many tics (read below the figure if there are too many), then this could be done scaling the curve itself beyond 2000, and then adding all the tics by hand. Since I don't have IR spectrum data available I will use the dummy file "+" and plot log(x) from 4000 to 500:
xmax=4000 ; xmin = 500
pivot = 2000 ; rescfactor = 2.
rescale(x) = (x >= pivot ? x : pivot + rescfactor*(x-pivot))
set xrange [rescale(xmax):rescale(xmin)]
set xtics ("4000" 4000, "3000" 3000, "2000" 2000, \
"1500" rescale(1500), "1000" rescale(1000), "500" rescale(500))
plot "+" u (rescale($1)):(log($1)) w l
In your case you just substitute log($1) by 2 or whatever you're plotting.
In newer versions of gnuplot (starting from 4.4) adding the tics can be done automatically using a loop:
xmax = 4000 ; xmin = 500 ; step = 500
set xtics (sprintf("%i",xmax) rescale(xmax)) # Add the first tic by hand
set for [i=xmin:xmax-step:step] xtics add (sprintf("%i",i) rescale(i))
Starting from gnuplot 4.6 also a different for construction can be made using do for:
do for [i=xmin:xmax-step:step] {set xtics add (sprintf("%i",i) rescale(i))}

Anyone have a way to plot a bean plot in gnuplot?

Title is pretty self explanatory but here is a picture of what I'd like to do. I'm having a tough time figuring out if its even possible.
Plot borrowed from:
Evaluation of geochemical background levels around sulfide mines – A new statistical procedure with beanplots. Gusstavason et al. 2012.
Doing the plot in exactly this orientation could be very cumbersome, if possible at all.
My suggestion is to plot everything with the usual orientation (i.e. having the 'sediments' axis as x-axis, or rather as x2-axis), rotate all labels a bit and finally rotate the complete output by 90 degree (pdf file with e.g. pdftk etc).
With this you can use any plot style as usual. In the script below I just show you how to plot the violet and yellow filled curves (using pseudo data) for two different data sets. Adding the other peaks should be straight forward (plot the bars with e.g. boxes or vector plotting style).
In order to have distinct ytics for the different plots, I associated a certain y-value with a certain plot, 1=Water, ..., 4=Gyttja).
Putting all toghether gives the following script:
reset
set terminal pdfcairo linewidth 2
outfile='bean'
set output outfile.'.pdf'
set encoding utf8
set x2range [0.5:9000]
set logscale x2
set x2tics (1, 5, 10, 50, '' 100, 500, '' 1000, 5000) out
set x2label 'mg/kg (sediments), µg/L (water)'
unset xtics
set yrange[0.5:4.5]
set ytics ('Water' 1, 'Minerogenic' 2, 'Peat' 3, 'Gyttja' 4) center rotate by -90 out
set label at graph 0.95, graph 0.05 right rotate by -90 'Nickel' font ',20' front
# cover possible data overlapping with the label
set object rectangle from graph 0.9, graph 0 to graph 1,graph 0.2 fillcolor rgb 'white' fillstyle solid noborder front
unset key
set macros
fs1="fillcolor rgb '#fc9e00' linewidth 2 fillstyle solid border lt -1"
fs2="fillcolor rgb '#9119f7' linewidth 2 fillstyle solid border lt -1"
# use pseudo data
set samples 500
plot '+' using 1:(4-0.3*exp(-(($1-10)/5.0)**4)) axes x2y1 with filledcurves y1=4 #fs1,\
'' using 1:(4+0.2*exp(-(($1-70)/50.0)**4)) axes x2y1 with filledcurves y1=4 #fs2,\
'' using 1:(1-0.4*exp(-(($1-5)/2.0)**2)) axes x2y1 with filledcurves y1=1 #fs1,\
'' using 1:(1+0.1*exp(-(($1-30)/20.0)**2)) axes x2y1 with filledcurves y1=1 #fs2
set output
system(sprintf('pdftk %s.pdf cat 1W output %s-rot.pdf', outfile, outfile))
system(sprintf('pdftocairo -r 150 -png %s-rot.pdf', outfile))
This gives (conventional and rotated output side-by-side) with 4.6.3:
Some stuff is required for the pseudo data. For a real data file, the plotting line looks a bit differently. The different plots have a separation of 1 in y-direction, so you must scale your data accordingly (done here manually with a scaling factor sc):
sc = 5.1
plot 'datafile.txt' using 1:(4 + $2/sc) axes x2y1 with filledcurves y1=4 #fs1
You can of course also do the scaling automatically, by extracting some minimum/maximum values using the stats command.

3D Mapped Graph with Gnuplot Not accurate

I am encountering problems while trying to create a 3D (2D mapped) graph.
The data I am generating should create a 3 dimensional normal distribution bump, or, when "mapped", it should look like a flattened 3D graph, with color used as the third dimension
The script I am using to generate the mapped graph is the following:
#!/usr/bin/gnuplot
reset
#set terminal png
set term postscript eps enhanced
set size square
set xlabel "X position"
set ylabel "Y position"
#set zlabel "Synaptic Strength"
#Have a gradient of colors from blue (low) to red (high)
set pm3d map
set palette rgbformulae 22,13,-31
#set xrange [0:110]
#set yrange [0:80]
#set zrange [0:1]
set style line 1 lw 1
#set title "Title"
#Don't want a key
unset key
#set the number of samples
set dgrid3d 51,51
set hidden3d
splot DataFile u 1:2:3
when I run it on the following DataFile (http://www.sendspace.com/file/ppibyw)
I get the following output
The legend indicates a z-range of 0-0.03, however, the datafile has far larger z-values, such as 0.1. Obviously I can't publish a graph that is so inaccurate. Furthermore, I need a better graph in order to gain a better insight as to what is wrong with my simulation.
Does anyone know why gnuplot handles 3d mapped graphs like this? I suspect it has to do with the number, and nature, of the samples.
You problem is in the set dgrid3d 51,51
Have a look at what happens if you write set dgrid3d 51,102 (much better) or set dgrid3d 51,500 (much worse)
The point is that (from the help)
The grid is equally spaced in x
(rows) and in y (columns); the z
values are computed as weighted
averages or spline interpolations of
the scattered points' z values. In
other words, a regularly spaced grid
is created and the a smooth
approximation to the raw data is
evaluated for all grid points. Only
this approximation is plotted, but
not the raw data.
You could try and improve the approximation if you want see the help (?dgrid3d), but I would rather just plot the data straight. You can do this by ditching the dgrid3d command altogether. You will have to modify your data file so that there is a blank line when the x coordinate changes. For example
3.10000000000000142109 4.15692193816530508599 0.00004084299890679580
3.10000000000000142109 4.33012701892219364908 0.00001123746243460237
3.15000000000000124345 0.08660254037844386521 0.00000816290100763514
3.15000000000000124345 0.25980762113533162339 0.00001935936190868058
Then with this simplified script
set terminal png![enter image description here][1]
#set size square
set xlabel "X position"
set ylabel "Y position"
#uncomment the next command to eliminate the mysterious glitch around x=3.4
set yrange [0.1:4.5]
set pm3d map
set output "grid_merged.png"
splot "grid_merged2.dat" u 1:2:3
set output
set term pop
I get
which is better than you get with the interpolated plot. I'm not sure what causes the glitch aroung 3.4, its not there on other (non-mapped) views - altering the yrange eliminates it - although I'm not sure it changing the y-range is cheating in terms of your simulation results....

Resources