I am trying to plot a filled curve with Gnuplot. If I set the Y range to a large value, the filled curve is plotting just fine. However, when I use a small Y range, some part of the curve are not filling with colors.
set terminal postscript color size 3.25,3.25 font "Helvetica, 8"
set output "test.ps"
set key at screen 0.95,0.70 right bottom
set border lt 1 lc 0 lw 1
set lmargin at screen 0.25
set rmargin at screen 0.95
set tmargin at screen 0.675
set bmargin at screen 0.15
set xlabel "X"
set ylabel "Y"
set xr [-1:2]
set yr [0:160]
set format x "%2.1f"
set style fill transparent solid 0.4
plot "data" w filledcurve x1 lt 1 lw 0.1 lc rgb "red"
This figure is the one with large Y range which is just fine.
This one is the figure with small Y range which is not plotting well.
The data file is available here. https://drive.google.com/drive/folders/1OIHLT2Mz4QGX3VKeZCGM_S4VjTO0FuOc?usp=sharing
Any comment or solution would be appreciated. Thank you all!
No such problem in gnuplot version 5 (confirmed back to version 5.0 patchlevel 3).
Output from current 5.2.4 shown.
I want to do a vector field plot with the vector arrows also depicted at the bottom just like in a surface contour plot using "set pm3d at b".
My file is given in the following format:
x y y dx dy dz
1 0 2 4 3 1
2 3 4 2 6 3
2 4 6 1 9 2
. . . . . .
I have used this gnuplot script:
set style arrow 1
set xrange[0.7:0.0]
set yrange[-0.4:0.4]
set zrange[-0.4:1.0]
set xtics (-0.7,-0.5,-0.33,-0.15,0.0,0.15,0.33,0.5,0.7) font "Times-Roman,18"
set ytics (-0.7,-0.5,-0.33,-0.15,0.0,0.15,0.33,0.5,0.7) font "Times-Roman,18"
unset ztics
set palette rgbformulae 30,31,32
set ticslevel 0
unset key
scale = 0.4
splot 'file.dat' u 1:2:3:($4*scale):($5*scale):($6*scale) w vectors arrowstyle 1
I also attached two 3d vector field plots with different views. What I actually want is a combination of both so that the contour of the plotted vectors should appear at the bottom (just like a top view using "set view 0,180" which is represented by the second image (top view) incorporated into the (side view) plot.
Vector_field_3d_plot_side_view
Vector_field_3d_plot_top_view
Since I havenĀ“t seen any gnuplot example for such a plot, I am not sure even if it is capable of doing it. If not, which software (Matlab, matplotlib,...) would you recommend me to use instead?
Thanks in advance!
I really appreciate any help!
Best wishes,
DaveS
Since you know the zrange, you can simply do the projection yourself and set z to the minimum value of the z-axis and dz to zero:
set style arrow 1
set xrange[0.7:0.0]
set yrange[-0.4:0.4]
set zrange[-0.4:1.0]
set xtics (-0.7,-0.5,-0.33,-0.15,0.0,0.15,0.33,0.5,0.7) font "Times-Roman,18"
set ytics (-0.7,-0.5,-0.33,-0.15,0.0,0.15,0.33,0.5,0.7) font "Times-Roman,18"
unset ztics
set palette rgbformulae 30,31,32
set ticslevel 0
unset key
scale = 0.4
splot 'file.dat' u 1:2:3:($4*scale):($5*scale):($6*scale) w vectors arrowstyle 1,\
'' u 1:2:(-0.4):($4*scale):($5*scale):(0) w vectors as 1
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 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 want to plot a 18x18 matrix with gnuplot. Here is my codes:
set size ratio 1
set palette gray negative
set xrange[-0.5:17.5]
set yrange[-0.5:17.5]
set cbrange[-0.2:0.8]
set xtics 0,1,17
set ytics 0,1,17
set xtics offset -0.5,0
set title "Resolusition Matrix for E"
plot "Mat" matrix w image noti
Then I got a fig like this:
Now I would like to add borders to each cell, which will look like this:
Thank you.
For your case you can set one minor tic, which then lies on the border between two pixels, and draw a grid on them:
set size ratio 1
set palette gray negative
set autoscale xfix
set autoscale yfix
set xtics 1
set ytics 1
set title "Resolution Matrix for E"
set tics scale 0,0.001
set mxtics 2
set mytics 2
set grid front mxtics mytics lw 1.5 lt -1 lc rgb 'white'
plot "Mat" matrix w image noti
Note, that set grid front also brings the tics to the front. To avoid that you can scale the tics to 0. For the minor tics you must use a very small number, 0 would omit the grid lines on the minor tics.
The result with 4.6.3 is:
EDIT: In order to control the grid lines and tic labels independently, you can use the unused x2 and y2 to draw the grid (inspired by an answer to How do I draw a vertical line in gnuplot?):
set size ratio 1
set palette gray negative
# grid lines
set x2tics 1 format '' scale 0,0.001
set y2tics 1 format '' scale 0,0.001
set mx2tics 2
set my2tics 2
# labeling
set xtics 5 out nomirror
set ytics 5 out nomirror
set grid front mx2tics my2tics lw 1.5 lt -1 lc rgb 'white'
set xrange[-0.5:39.5]
set yrange[-0.5:39.5]
set x2range[-0.5:39.5]
set y2range[-0.5:39.5]
plot "Mat" matrix w image notitle
With gnuplot version 4.6, this requires setting explicit ranges, so that the x and x2 (unused!) are equal. The information might be extracted with stats from the data file.
Using version 5 allows you to use set link. Instead of all the set *range stuff. You could use:
set autoscale fix
set link x
set link y
Result: