Gnuplot 5: color gradient shading between curves - colors

This was created with Matplotlib. Is it possible to make the same type of shading in Gnuplot 5?

I'm not aware that gnuplot has a gradient fill option, but I could be wrong.
The following is a bit of an "ugly" workaround. You basically create 3 plots on top of each other. You might want to adjust the palette to get the desired colors and a smooth transition.
a dummy plot to get the palette as background (i.e. the colorbox as large as the graph)
cover the part above y>f(x) and y>0 to x2-axis as well as below y<f(x) and y<0 to x1-axis.
plot again f(x) to see f(x) and the axes tics again
Edit:
The earlier version of the code used multiplot. It's not necessary, just use set colorbox back. But then set xzeroaxis ls -1 is not visible anymore, add plot 0 w l ls -1 instead.
Code:
### filled curve with gradient
reset session
f(x) = sin(x)/(1+x)
fabove(x) = f(x)<0 ? 0 : f(x)
fbelow(x) = f(x)>0 ? 0 : f(x)
set samples 200
set palette defined (0 "white", 1 "red", 2 "black")
set colorbox back user origin graph 0, graph 0 size graph 1, graph 1
unset cbtics
set xrange[0:15]
set xzeroaxis ls -1
set yrange[-0.2:0.5]
plot fabove(x) w filledcurves x2 fc rgb "white" not, \
fbelow(x) w filledcurves x1 fc rgb "white" not, \
f(x) w l lw 2 lc rgb "black", \
NaN palette, \
0 w l ls -1
### end of code
Result:

Related

Clip vectors on circle in gnuplot

I try to draw some vector fields in a circular region. Consider the following MWE
unset grid
unset tics
unset colorbox
unset border
set size square
besselj(n, x) = n > 1 ? 2*(n-1)/x*besselj(n-1,x) - besselj(n-2,x) : (n == 1 ? besj1(x) : besj0(x))
dbesselj(n, x) = n/x*besselj(n,x) - besselj(n+1,x)
rho(x,y) = sqrt(x**2+y**2)
phi(x,y) = atan2(y,x)
d = 1.0
l = 1.0
z = l/2
q = 1
set xrange [-d/2*1.1:d/2*1.1]
set yrange [-d/2*1.1:d/2*1.1]
Erho(x,y,n,ynp) = (-1/rho(x,y)) * besselj(n, (ynp*2/d)*rho(x,y)) * (-n*sin(n*phi(x,y))) * sin(q*pi*z/l)
Ephi(x,y,n,ynp) = (ynp*2/d) * dbesselj(n, (ynp*2/d)*rho(x,y)) * (cos(n*phi(x,y))) * sin(q*pi*z/l)
Ex(x,y,n,ynp) = rho(x,y) > d/2 ? NaN : cos(phi(x,y))*Erho(x,y,n,ynp) - sin(phi(x,y))*Ephi(x,y,n,ynp)
Ey(x,y,n,ynp) = rho(x,y) > d/2 ? NaN : sin(phi(x,y))*Erho(x,y,n,ynp) + cos(phi(x,y))*Ephi(x,y,n,ynp)
mag(x,y,n,ynp) = sqrt(Ex(x,y,n,ynp)**2 + Ey(x,y,n,ynp)**2)
set object circle at 0,0 size 0.5 fc black lw 3 front
set multiplot layout 1,2
set title 'TE_{01}'
set table 'tmp.dat'
set samples 16
set isosamples 16
plot '++' u 1:2:(Ex($1,$2,0,3.832)/50):(Ey($1,$2,0,3.832)/50) w vectors
unset table
set samples 250
set isosamples 250
plot '++' u 1:2:(mag($1,$2,0,3.832)) w image notitle, \
'tmp.dat' u 1:2:3:4 w vectors head filled lc black lw 1 notitle
set title 'TE_{11}'
set table 'tmp.dat'
set samples 16
set isosamples 16
plot '++' u 1:2:(Ex($1,$2,1,1.841)/20):(Ey($1,$2,1,1.841)/20) w vectors
unset table
set samples 250
set isosamples 250
plot '++' u 1:2:(mag($1,$2,1,1.841)) w image notitle, \
'tmp.dat' u 1:2:3:4 w vectors head filled lc black lw 1 notitle
unset multiplot
which plots the vector field as well as its magnitude inside the circle with diameter d. The result from this is
which is totally okay for the left image (TE01), but the right image (TE11) looks ugly because there are some vectors which are drawn outside the circle. My actually desired result is this
where I have no vectors outside of the black circle. How can I achieve that?
I know there is the clip function in gnuplot, but this does not allow to specify the shape to be used for clipping.
Here is what you can try. Define your own clip function, e.g. a circle.
First you need to check whether a data point is outside of your circle or not.
Clip(x,y) returns NaN if it is outside and 0 if it is inside.
Now, when you plot simply add the value of the clip function to your value. Your data will be clipped within a circle because something +0 remains unchanged and something +NaN will be NaN and will not be plotted. It is sufficient if you do this just for x (vector start) and x + delta x (vector end).
Code:
### clip function in circle form
reset session
set size square
# create some test data
set samples 25
Scaling = 0.5
set table $Data
plot [-5:5] '++' u 1:2:(Scaling*$1/sqrt($1**2+$2**2)): \
(Scaling*$2/sqrt($1**2+$2**2)) : (sqrt($1**2+$2**2)) with table
unset table
set palette rgb 33,13,10
CenterX = 0
CenterY = 0
Radius = 3.5
Clip(x,y) = sqrt((x-CenterX)**2 + (y-CenterY)**2) > Radius ? NaN : 0
set xrange[-6:6]
set yrange[-6:6]
set multiplot layout 1,3
plot $Data u 1:2:3:4:5 w vec lc pal not
plot $Data u ($1+Clip($1,$2)):2:($3+Clip($1+$3,$2+$4)):4:5 w vec lc pal not
CenterX = 1
CenterY = 1
plot $Data u ($1+Clip($1,$2)):2:($3+Clip($1+$3,$2+$4)):4:5 w vec lc pal not
unset multiplot
### end of code
Result:

Plotting two parallel charged plate configuration in Gnuplot

I want to plot a parallel plate capacitor setup with plates at x = -1 and x = +1 lying in the yz plane. I have to then show the potential varying in between them and the vector plot of electric field.
How can I generate the solid plates in 3D?
I am not sure if Gnuplot is the best tool for this, nevertheless an approximation could be perhaps achieved with parametric plotting, where the x-coordinate is fixed and y/z are directly mapped to the u/v parameters:
set terminal pngcairo rounded font ",16"
set xr [-4:4]
set yr [-4:4]
set zr [-4:4]
set palette defined ( 0 "black", 1 "#666666" )
set pm3d at s
unset surface
unset colorbox
set isosamples 100
unset key
set parametric
set ur [-2:2]
set vr [-2:2]
splot \
-1,u,v w l lc rgb '#333333', \
+1,u,v w l lc rgb '#333333'
#or set larger ur/vr and use, e.g.,
# -1,(u>-2&&u<2?u:1/0),(v>-2&&v<2?v:1/0) w l lc rgb '#333333', \
# +1,(u>-2&&u<2?u:1/0),(v>-2&&v<2?v:1/0) w l lc rgb '#333333'
This would give you:

Gnuplot: 3D Surface Outline

I am plotting a simple 3D surface in GNUPlot for the following function:
f(x,y)=x**2-y**2
This works fine. However I would like to only display the outline of the surface. Without the colors or grid lines along it. Is there a way to achieve this?
Here is an example of what I am looking to create:
Outline of the surface
Thank you for your help.
In this specific case you could also adjust the number of isolines drawn by gnuplot:
f(x,y) = x**2 - y**2
set xr [-10:10]
set yr [-10:10]
unset key
set isosamples 2,3
splot f(x,y)
I'm not aware of a general solution. In your special case I would consider just drawing each single line using parametric mode like in this script:
f(x,y) = x**2 - y**2
set parametric
set urange [-10:10]
set vrange [-10:10]
set nokey
#set border 0 # uncomment to remove the axes
#unset xtics
#unset ytics
#unset ztics
set arrow 1 from 0,0,0 to 0,0,100
set arrow 1 head lw 2
splot u,-10,f( u,-10) lc 0, \
u, 10,f( u, 10) lc 0, \
-10, v,f(-10, v) lc 0, \
10, v,f( 10, v) lc 0, \
u, 0,f( u, 0) lc 0
This is the result:

gnuplot xtics disapper when using logscale

I'm pretty new to gnuplot, so I'm thankful for every advice.
Right now, I am trying to plot some data using the logscale command. But I don't know why all the xtics disappear when I use the logscale. This is the script I use:
#creates a plot of all the four different loops with a logscale. Fits the functions as well and saves the fitting data
#in a file named fitting.dat
set size 1,1
# set logscale
set logscale y 10
set logscale x 10
#set xlabel and y label
set xlabel "Dimension of Matrix"
set ylabel "time [s]"
#scale plot
set xrange [450:850]
set yrange[0.01:5]
#nothing displayed from fitting
set fit quiet
#position of legend
set key top right
set key horizontal
# guessing the parameters, the fit will be better and we know that the exponent should be \approx 3
b=3
d=3
f=3
h=3
#Define all th four different data fitting functions, asuming f(x) ~ a*x^b
f(x)= a*x**b
g(x)=c*x**d
h(x)=e*x**f
j(x)=g*x**h
#fit the different functions
fit f(x) 'matmul.txt' using 1:2 via a,b
fit g(x) 'matmul.txt' using 1:3 via c,d
fit h(x) 'matmul.txt' using 1:4 via e,f
fit j(x) 'matmul.txt' using 1:5 via g,h
# save the fitting parameters in an extra file
set print 'fitting.dat'
print 'function'
print a,'*x', '**', b , ' rows'
print c,'*x', '**', d , ' cols'
print e,'*x', '**', f , ' intrinsic function'
print g,'*x', '**', h , ' lapack routine'
# plot everything
plot "matmul.txt" u 1:2 t "rows" ,\
"matmul.txt" u 1:3 t "cols" ,\
"matmul.txt" u 1:4 t "intrinsic" ,\
"matmul.txt" u 1:5 t "lapack" ,\
f(x) t sprintf("row:%.2e*x^(%.2f)", a,b),\
g(x) t sprintf("col:%.2e*x^(%.2f)",c,d),\
h(x) t sprintf("int:%.2e*x^(%.2f)",e,f),\
j(x) t sprintf("lap:%.2e*x^(%.2f)",g,h)
#choose output format
set terminal png
set output "time.png"
replot
#now, non-logarithmic plot
#unset logscale
set yrange[0.01:1]
unset logscale
#plot again
plot "matmul.txt" u 1:2 t "rows" ,\
"matmul.txt" u 1:3 t "cols" ,\
"matmul.txt" u 1:4 t "intrinsic" ,\
"matmul.txt" u 1:5 t "lapack" ,\
f(x) t sprintf("col:%.2e*x^(%.2f)", a,b),\
g(x) t sprintf("row:%.2e*x^(%.2f)",c,d),\
h(x) t sprintf("int:%.2e*x^(%.2f)",e,f),\
j(x) t sprintf("lap%.2e*x^(%.2f)",g,h)
My Input file 'matmul.txt' looks like this:
#Dim rows cols intrinsic lapack
500 0.1320E+00 0.1040E+00 0.6800E-01 0.2000E-01
520 0.1400E+00 0.1320E+00 0.5600E-01 0.2000E-01
540 0.1480E+00 0.1400E+00 0.6000E-01 0.3200E-01
560 0.1680E+00 0.1480E+00 0.7200E-01 0.2400E-01
580 0.1800E+00 0.1680E+00 0.6800E-01 0.3200E-01
600 0.1920E+00 0.1960E+00 0.7200E-01 0.3600E-01
620 0.2080E+00 0.2040E+00 0.9600E-01 0.2000E-01
640 0.4000E+00 0.3520E+00 0.8400E-01 0.3200E-01
...
Now, If I run this file, I obtain the following output plot
I don't know why, but the range of the yscale is not correct and the xtics are not displayed. If I plot it without 'logscale', the plot is exactly what I want. Why doesn't this work?
Tics in logarithmic plots are not separated by a constant summand as in 1, 2, 3, ..., they are separated by a constant factor as in 1, 10, 100, ...
This means in your case for the y-axis: You have given the range [0.01:5], leading to tics at 0.01, 0.1, 1 as it is seen in the picture. Above 1, you have minor tics at 2, 3, 4, and 5. 5 is the upper boundary of the graph as specified in the range. To also have a label at this tic, just add it with:
set ytics add (5)
or change the yrange to one of
set yrange [0.01:1]
set yrange [0.01:10]
For your xtics: Labels would be at 1, 10, 100, 1000, ... But your range is from 450 to 850: no labeled xtic inside.
Again, you can set them manually:
set xtics (450, 550, 650, 750, 850)
Your x-axis spans less than a decade and the default major tic frequency is a decade. If you want labeled tics within this range use set xtics (400,500,600,700,800) or whatever you want.
This is all in the documentation, just search for "logscale"

Normalized histograms in gnuplot with added function plot

I have the following script to plot histograms:
set terminal postscript eps enhanced color
set title "Histogram\_CreatesFile"
colour1="#00A0ff"
colour2="navy"
colour3="#ffA000"
colour4="#800000"
set output 'Histogram_CreatesFile.eps'
set yrange [0:]
set style fill solid 0.8 border -1
bin_width = 0.2
set boxwidth bin_width
bin_number(x) = floor(x/bin_width)
rounded(x) = bin_width * ( bin_number(x) + 0.5 )
plot 'Histogram_CreatesFile.txt' using (rounded($1)):(1) smooth frequency with boxes lc rgb colour1 notitle
This is supposed to be empirical realisation of some distribution, so to make it more clear I would like to:
Normalize the bars appropriately so that they can be compared to a density function (I guess the sum of the areas of the bars should sum-up to unity? That would mean that the height of each bar should be divided by barWidth*numberOfElements)
On the same picture plot the theoretical distribution function, given by a closed form formula (e.g. Gaussian)
How can I achieve this?
I managed to solve this issue.
(1) The normalization goes into the column after the colon, so the plot command becomes:
plot 'ConfUoMBM1validation0_0.txt' using (rounded($1)):(1/(bin_width*STATS_records)) smooth frequency with boxes lc rgb colour1 notitle
(2) Plotting of functions can't be easier, just do it after a coma as you would normally do
So the final outcome is:
set terminal postscript eps enhanced color
set title "ConfUoMBM1validation0 0"
colour1="#00A0ff"
colour2="navy"
colour3="#ffA000"
colour4="#800000"
set output 'ConfUoMBM1validation0_0.eps'
set style fill solid 0.8 border -1
bin_width = 0.926911
set boxwidth bin_width
bin_number(x) = floor(x/bin_width)
rounded(x) = bin_width * ( bin_number(x) + 0.5 )
invsqrt2pi = 0.398942280401433
normal(x,mu,sigma)=sigma<=0?1/0:invsqrt2pi/sigma*exp(-0.5*((x-mu)/sigma)**2)
stats 'ConfUoMBM1validation0_0.txt' using (rounded($1)) nooutput
set xrange [STATS_min-bin_width/2.:STATS_max+bin_width/2.]
set yrange [0:]
plot 'ConfUoMBM1validation0_0.txt' using (rounded($1)):(1/(bin_width*STATS_records)) smooth frequency with boxes lc rgb colour1 notitle, normal(x,-0.14166974006432781,4.6345562297659741) with lines lc rgb colour2 lw 5 notitle

Resources