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