Disclaimer: I am totally new to Gnuplot, so I am probably missing something obvious...
For a presentation that I have to give, I am trying to use Gnuplot for creating an interactive version of this plot.
Up to now, I have come up with the following code:
set hidden3d
set isosamples 40
set border 4095
set xrange [-1 : 5]
set yrange [-3 : 3]
set zrange [-10 : 10]
set xtics 2
set ytics 2
set ztics 2
f(x,y) = x**2 + y**2 * (1 - x)**3
splot f(x,y)
pause -1
However, at the boundary of the plot (specifically, at the boundary with respect to the z-axis) the plot gets truncated in a way that I find quite ugly; see below. What I would like is essentially that all the lines get drawn as if my plot range would be (e.g.) -50 : 50, but then in the end only the "intersection" of the plot with the box [-1:5] x [-3:3] x [-10:10] should actually be shown. What seems to be happening right now is that any "plot segment" that has at least one point outside the box determined by xrange-zrange gets not drawn at all.
(How) can I change this?
Answering from the future, sort of, so this may not count...
Versions of gnuplot through 5.2 cannot do exactly what you want. However the development version 5.3 does this by default so long as you use a pm3d surface rather than a hidden3d surface. Here is your plot as rendered by the current development code:
set border 4095
unset colorbox
set view 56, 15, .75, 1.75
set samples 40, 40
set isosamples 40, 40
set xyplane 0
set grid x y z vertical
set pm3d depthorder border linewidth 0.100
set pm3d clip z
set pm3d lighting primary 0.8 specular 0.3 spec2 0.3
set xrange [-1 : 5]
set yrange [-3 : 3]
set zrange [-10 : 10]
set xtics 1 offset 0,-0.5
set ytics 1 offset 0,-0.5
set ztics 5
f(x,y) = x**2 + y**2 * (1 - x)**3
splot f(x,y) with pm3d fillcolor "cyan"
The key is the command set pm3d clip z. This will be the default in future versions but is not supported in version 5.2. You can build from the current git source repository on gnuplot.sf.net or wait for the release of version 5.4 expected in Spring 2020.
Maybe you can the following line of code to force the zrange.
set ticslevel 0
I have a simple data I want to plot as 3D plot (3 columns divided by a comma):
33.26,0.0000001,1
67.02,0.0000010,2
101.64,0.0000100,3
137.53,0.0001000,4
175.06,0.0010000,5
214.59,0.0100000,6
256.47,0.1000000,7
301.09,1.0000000,8
348.78,10.0000000,9
399.92,100.0000000,10
454.87,1000.0000000,11
513.99,10000.0000000,12
577.65,10000.0000000,13
646.22,10000.0000000,14
720.05,10000.0000000,15
799.51,10000.0000000,16
884.96,10000.0000000,17
976.77,10000.0000000,18
1075.29,10000.0000000,19
1180.89,10000.0000000,20
1293.92,10000.0000000,21
1414.77,10000.0000000,22
1431.83,10000.0000000,23
1449.15,10000.0000000,24
1466.97,10000.0000000,25
1485.79,10000.0000000,26
1505.97,10000.0000000,27
1527.88,10000.0000000,28
1551.87,10000.0000000,29
1578.3,10000.0000000,30
1607.56,10000.0000000,31
1639.98,10000.0000000,32
1675.95,10000.0000000,33
1715.82,10000.0000000,34
1759.96,10000.0000000,35
1808.72,10000.0000000,36
1862.49,10000.0000000,37
1921.6,10000.0000000,38
1986.44,10000.0000000,39
2057.35,10000.0000000,40
2134.71,10000.0000000,41
2218.87,10000.0000000,42
2310.2,10000.0000000,43
2409.06,10000.0000000,44
2515.83,10000.0000000,45
I wrote a simple script to plot the above data:
#!/usr/bin/gnuplot
set palette rgbformulae 33,13,10
set datafile separator ","
set terminal postscript eps size 10.5, 5.62 enhanced color font 'Helvetica,20' linewidth 2
set output 'test.eps'
set xlabel "time [s] (no operation)" offset -4, 0, 0
set xtics left offset 0,-0.3 rotate by 45 right
set xrange [0:400]
set ylabel "ranges" offset 2, 0, 0
set ytics left offset 0,-0.5
set zlabel "devices" offset -4, 0, 0
set zrange [0:50]
set autoscale
set title " "
set key inside left top;
set dgrid3d 30,30
set hidden3d
set style line 1 linecolor rgb '00FF00' linetype 4 linewidth 1
splot "data.csv" u 1:2:3 title "" with lines palette
And my output:
As you all can see, the output image (or, I should say), the x,y and z ticks on axis x,y, and z are not enough detailed. It is hard to say that the output image was plotted with this data.
Is there a way that would let me manipulate the x,y, and z ticks, to be taken from file, in some elegant way?
I also would like the image to be more readable with new x,y, and z ticks, so I think that the 10000.0000000 value should appear only once, when it appeared for the first time in data file.
Thank you.
Not exactly an answer to your question, and it is my personal opinion, but you might be interested in the ideas:
The data seems not to be grid data, so I would not use a surface plot of any kind.
Plotting only the datapoints in 3d does not give a useful picture, it is only a single line somewhere in space. I would try to use a 2D plot which contains the height information as color.
I would use a logscale for the y-axis.
This leads to the following script:
set terminal pngcairo
set output 'test.png'
set datafile separator ","
set palette rgbformulae 33,13,10
# Set margins to keep colorbox label inside the picture
set lmargin screen 0.12
set rmargin screen 0.85
set xlabel "time [s] (no operation)"
set ylabel "ranges"
set cblabel "devices"
unset key
set yrange [1e-8:1e5]
set ytics format "1e%+T"
set logscale y
set view map
set cbrange [0:50]
set zrange [0:50]
splot "data.csv" u 1:2:3 w p pt 7 palette ,\
"data.csv" every 5::4 u ($1+0):($2/3):(0):($3 != 30 ? 3 : "") with labels
It also prints the z-labels of some datapoints, skipping 30 for spacing reasons.
This is the result:
i am 3d plotting a matrix with some values, and i need to add contour lines to the plot, is there a simple gnuplot command to do this?
I tried the command: "set contour base" but only 1 line came up, i think it should be many lines. See matlab picture
When i plot it in gnuplot i only get 1 contour line in the top left corner.But everything else is correct.
My goal is to get it to look like in matlab like this Matlabplot
I also found this example: see link in comments (dont have enough rep), but i dont understand where i should put in the data values from test.txt
test.txt
test.txt
gnuplot commands
set view map
set yrange [0:30]
set xrange [0:30]
set dgrid3d 100,100,4
set contour base
splot 'test.txt' u 1:2:3 w pm3d
What you are missing is to tell gnuplot where to put the contours. This is done via the set cntrparam levels incr -0.3,0.1,0.5 command which means: start at -0.3 and trace a contour every o.1 up to 0.5.
AFAIK if you want to make contours all black, you have to save the contour lines in a temporary file (here contour.txt).
So your script would be
reset
set contour
unset surface
set cntrparam levels incr -0.3,0.1,0.5
set view map
set xrange [0:30]
set yrange [0:30]
set dgrid3d 100,100,4
set table "contour.txt"
splot 'test.txt'
unset table
unset contour
set surface
set table "dgrid.txt"
splot 'test.txt'
unset table
reset
set pm3d map
unset key
set palette defined (0 '#352a87', 1 '#0363e1',2 '#1485d4', 3 '#06a7c6', 4 '#38b99e', 5 '#92bf73', 6 '#d9ba56', 7 '#fcce2e', 8 '#f9fb0e')
set autoscale fix
set grid
splot 'dgrid.txt' w pm3d, 'contour.txt' w l lc rgb "black"
which gives you this:
Note:
you can get rid of interpolation file (dgrid.txt) if you format a bit your datafile by leaving a blank line after each row (i.e. every 30 datapoints) because they are already mesh-ordered.
This could be done also with a awk script. But I'm too lazy to look into it...
The rest will remain the same and will work as expected.
here is how it should look like :
In which case the script would simply become:
set pm3d map impl
set contour
set style increment user
do for [i=1:18] { set style line i lc rgb "black"}
set cntrparam levels incr -0.3,0.1,0.5
set palette defined (0 '#352a87', 1 '#0363e1',2 '#1485d4', 3 '#06a7c6', 4 '#38b99e', 5 '#92bf73', 6 '#d9ba56', 7 '#fcce2e', 8 '#f9fb0e')
set autoscale fix
splot 'test.txt' w pm3d notitle
with no need of ntermediate file and with better contour since data in not interpolate by gridded:
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))}
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