I have a single set of value for X. Otherwise I have three set of Y values let it be y1,y3,y4.
Now, I am unable to plot X versus y1,y3,y4 in the same plot in GNUPLOT.
Can anyone help me out to solve this problem?
If you have your data in a file, assuming data.dat
X1 Y1 Y2 Y3
1 0.1 0.2 0.3
... ... ... ...
you can plot Y1, Y2 and Y3 versus X with
plot 'data.dat' using 1:2, '' u 1:3, '' u 1:4
u being the shortcut for using.
If all y values are of the same units, then one y axis would suffice. If not, you can plot x against up to 2 y-axes (here's how).
You use the 'axes' option to plot. Here is an example drawing 2 plots using the same X values:
set xrange [-4:4]
plot cos(x) axes x1y1 title "cos" with linespoints lt 1 pt 7 ps 0.0,\
sin(x) axes x1y2 title "sin" with linespoints lt 2 pt 8 ps 0.0
pause mouse any "Click the mouse or hit any key to terminate"
If you run that with gnuplot it should look like the following image
Related
Is there a way in gnuplot to loop through data points in a data file? Let's say I have a file with the data
# x y
1 2
2 5
3 1
4 5
5 6
And I am looking how to draw lines in a loop from some x, y to some other x, y from the files. Something like:
j=0
x3 = data[1][1]
y3 = data[1][2]
do for [i=1:4] {
x1 = data[i][1]
y1 = data[i][2]
x2 = data[i+1][1]
y2 = data[i+1][2]
j=j+1
set arrow j from first x3,y3 to first x2,y1
j = j+1
set arrow j from first x2,y1, to first x2, y2
x3 = x2
y3 = y2
}
where data would be some array or matrix representation of data file. I think I could live with the ability to read the datafile into, say, 4 separate arrays. But i have not found anything even close to this.
Note that vector plotting is probably not general enough to cover this case.
If I interpreted your intention correctly, you want to plot a stepwise function.
There is a gnuplot plotting style with steps (check help steps).
However, if you want arrows it's probably getting a bit more complicated and you have to use the style with vectors or with arrows, check help vectors and help arrows.
Script:
### plotting steps with and without arrowheads
reset session
$Data <<EOD
# x y
1 2
2 5
3 1
4 5
5 6
EOD
set offsets 1,1,1,1
set key noautotitle
set multiplot layout 2,1
plot $Data u 1:2 w steps lw 2 lc "web-green"
plot x1=y1=NaN $Data u (x0=x1,x1=$1,x0):(y0=y1,y1=$2,y0):(x1-x0):(0) \
w vec head lw 2 lc "red", \
x1=y1=NaN '' u (x0=x1,x1=$1):(y0=y1,y1=$2): (0): (y0-y1) \
w vec backhead lw 2 lc "red"
unset multiplot
### end of script
Result:
I have text files like this:
NumberOfOrbital\tIt'sEnergy
I want to plot it as a horizontal sticks with a number of orbital on a left. When I am trying to plot it, I get points of given energy and number of orbital on x axis. What should I do??
In the gnuplot console check help vectors and help labels. I assume you are looking for something like this:
Code:
### horizontal lines with vectors and with labels
reset session
$Data <<EOD
A 1.10
B 1.50
C 1.70
D 2.10
E 2.50
F 3.30
G 3.60
EOD
unset xtic
set offset 1,1,1,1
set key noautotitle
set ylabel "Energy / a.u."
plot $Data u (0):2:(1):(0) w vec lw 2 lc "red" nohead, \
'' u (0):2:1 w labels offset -1,0
### end of code
Result:
I'm able to put an x axis on the top of a graph in gnu plot via
set x2label "label" and
set x2tics
I have a column of data of data1 values and I'd like to plot these values multiplied by two on the upper x axis against data data2 in the lower x axis. Both data1 and data2 are in the same data file. Here is some sample data
data2 data1
20 1.2e-2
40 3.0e-3
60 1.4e-3
... ...
I'd like to plot 2*data1 on upper axis against data2 on lower axis. Preferably, I'd like to just put a tick mark on the 2*data1 axis for every data2 value. On the y axis I will plot some other quantity against data2 but all I want to ask about here is how to plot x2 versus x1.
Thanks!
still guessing what exactly you want. Maybe we'll find out faster with this example.
reset session
$Data <<EOD
# x2 x1 y
20 1.2e-2 1
40 3.0e-3 2
60 1.4e-3 3
EOD
set key top center
set xtics nomirror
set x2tics nomirror
plot $Data u ($1*2):3 axes x2y1 w lp pt 7 title "y-data vs. x2-axis", \
'' u 2:3 axes x1y1 w lp pt 7 title "y-data vs. x1-axis"
Result:
Edit:
You can link x1 and x2 axes via a function (in the example below conversion between nm and eV) and then set your x2tics as desired.
Graph1: corresponding "odd" values from x1,
Graph2: "even" values by given interval x2tics 0.2,
Graph3: manual setting of x2tics.
Example:
### linked axes x1, x2
reset session
set xlabel "Wavelength / nm"
set xtics nomirror
set x2label "Energy / eV"
set x2tics nomirror
set link x via 1239.8/x inverse 1239.8/x
set ylabel "Intensity / a.u."
set ytics 0.2
set samples 400
Spectrum(x) = exp(-(x-500)**2/(400))
set xrange[380:780]
set multiplot layout 3,1
set format x2 "%.2f"
plot Spectrum(x) w l title "Spectrum"
set format x2 "%.1f"
set x2tics 0.2
replot
set x2tics ()
myTics = "1.7 1.8 1.9 2.0 2.1 2.3 2.5 2.7 3.0"
do for [i=1:words(myTics)] { set x2tics add (word(myTics,i) real(word(myTics,i))) }
replot
unset multiplot
### end of code
Result:
I am trying to use gnuplot to fill between a curve and the x axis for a certain xrange. For example I would like to fill between the line f(x)=x when x<5.
Example code:
set xrange [-10:10]
set yrange [-10:10]
set samples 100
plot x with filledcurves above x1=5
When this is plotted in Gnuplot 5.0 it does not show any fill.
I can try the reverse of:
plot x with filledcurves below x1=5
This gets closer because it fills below the line f(x)=x when x<5, however, it also shades the area above when x>5. There is also no way to limit it to above the x axis as well.
Any assistance would be appreciated. Thanks.
It seems there is no "direct" way to do it. Christoph gives a solution here.
Based on his code I came up with the following:
set xrange [-10:10]
set yrange [-10:10]
filter_lt(x,xmax) = ((x < xmax) ? x : 1/0)
f(x) = x
xmax = 5
plot '+' using (filter_lt($1,xmax)):(f($1)) with filledcurves x1 lt 1 notitle,\
'' using 1:(f($1)) with lines lw 2 lt 1 title 'f(x)=x'
I have a set of points "data" defining a curve that I want to plot with bezier smooth.
So I want to fill the area below that curve between some pairs of x values.
If I only had one pair of x values it's not that difficult because I define a new set of data and plot it with filledcu. Example:
The problem is that I want to do that several times in the same plot.
Edit: Minimal working example:
#!/usr/bin/gnuplot
set terminal wxt enhanced font 'Verdana,12'
set style fill transparent solid 0.35 noborder
plot 'data' using 1:2 smooth sbezier with lines ls 1
pause -1
Where the structure of 'data' is:
x_point y_point
And I realized that my problem is that in fact I can't fill not even one curve, it seems to be filled because the slope is almost constant there.
To fill parts below a curve, you must use the filledcurves style. With the option x1 you fill the part between the curve and the x-axis.
In order to fill only parts of the curve, you must filter your data, i.e. give the x-values a value of 1/0 (invalid data point) if they are outside of the desired range, and the correct value from the data file otherwise. At the end you plot the curve itself:
set style fill transparent solid 0.35 noborder
filter(x,min,max) = (x > min && x < max) ? x : 1/0
plot 'data' using (filter($1, -1, -0.5)):2 with filledcurves x1 lt 1 notitle,\
'' using (filter($1, 0.2, 0.8)):2 with filledcurves x1 lt 1 notitle,\
'' using 1:2 with lines lw 3 lt 1 title 'curve'
This fills the range [-1:0.5] and [0.2:0.8].
To give a working example, I use the special filename +:
set samples 100
set xrange [-2:2]
f(x) = -x**2 + 4
set linetype 1 lc rgb '#A3001E'
set style fill transparent solid 0.35 noborder
filter(x,min,max) = (x > min && x < max) ? x : 1/0
plot '+' using (filter($1, -1, -0.5)):(f($1)) with filledcurves x1 lt 1 notitle,\
'' using (filter($1, 0.2, 0.8)):(f($1)) with filledcurves x1 lt 1 notitle,\
'' using 1:(f($1)) with lines lw 3 lt 1 title 'curve'
With the result (with 4.6.4):
If you must use some kind of smoothing, the filter may affect the data curve differently, depending on the filtered part. You can first write the smoothed data to a temporary file and then use this for 'normal' plotting:
set table 'data-smoothed'
plot 'data' using 1:2 smooth bezier
unset table
set style fill transparent solid 0.35 noborder
filter(x,min,max) = (x > min && x < max) ? x : 1/0
plot 'data-smoothed' using (filter($1, -1, -0.5)):2 with filledcurves x1 lt 1 notitle,\
'' using (filter($1, 0.2, 0.8)):2 with filledcurves x1 lt 1 notitle,\
'' using 1:2 with lines lw 3 lt 1 title 'curve'