Using gnuplot, how can I plot sin(x) in the x-z plane and sin(x) in the x-y plane, both at the same time? - gnuplot

Using gnuplot, how can I plot sin(x) in the x-z plane and sin(x) in the x-y plane, both at the same time? I'm guessing I need to use the set parametric command and the splot command, but I can't seem to work out the rest! Does anyone know how to do this? I'm trying to generate a plot which demonstrates the nature of an electromagnetic wave. Thanks.

Yes, parametric mode is a possibility. For example, splot u,0,sin(u), u,sin(u),0 will plot the two (!) parametric curves u,0,sin(u) and u,sin(u),0. The variable u is the parametric dummy variable, for a simple sine function we only need one of them, even in 3d mode.
It might look a bit nicer with the following settings, but this is of course my biased opinion, far from finished, and depends on your needs:
set terminal pngcairo
set output "emfield.png"
set yrange [-2:2]
set zrange [-2:2]
set parametric
umax = 6*pi
set urange [0:umax]
unset border
unset xtics
unset ytics
unset ztics
# Set zeroaxes
set xyplane at 0
set arrow from 0,0,0 to (umax*1.1),0,0 size screen 0.020,15,60 filled
set arrow from 0,1,0 to 0,-1,0 size screen 0.020,15,60 filled
set arrow from 0,0,-1.4 to 0,0,1.4 size screen 0.020,15,60 filled
splot u,0,sin(u) lc 6, u,sin(u),0 lc 7
The result looks like this:

Related

gnuplot multiplot layout not being overridden by set origin, ways to position subplots

This question is to some part identical to what has already been asked here. But the referenced question never received the answer to the point whether the issue presented here is a bug or documentation confusion.
Documentation states with respect to the layout option of multiplot:
With the layout option you can generate simple multiplots without
having to give the set size and set origin commands before each plot:
Those are generated automatically, but can be overridden at any time.
My understanding of that text is that layout sets origin and size and at any time, i can change those specifications. Then this should work:
set xrange [0:10]
set multiplot layout 3,1 margins 0.1,0.95,0.12,0.95 spacing 0,0
unset key
plot cos(x) axes x1y1 w l ls 3 notitle
plot sin(x) axes x1y1 w l ls 3 notitle
set key bottom center out horizontal
plot sin(x) axes x1y1 w l ls 3 notitle
set origin 0.3,0.5
set size 0.2,0.1
set xrange [1:2]
plot cos(x) axes x1y1 w l ls 3 notitle
unset multiplot
But it does not. gnuplot completely ignores set size and set origin commands. What it should do is to plot 3 plots under each other and then create an inset at screen position (0.3,0.5) of size relative to canvas (0.2,0.1).
My questions are:
Is this a bug that should be reported or is this poorly formulated documentation issue (that layout can be overridden by set position and set size)?
multiplot offers two ways to position the sub-plots, set origin + set size and set *margin where * stands for one of b,t,l,r. Can someone provide a deeper explanation when one should use which? (For me it feels the proper way that was meant to do it is set origin and margins just became a dirty trick that works but was not meant for that)
What would be the cleanest way to produce the plot that I am looking for that would be easily reproducible (for any other problem, not just 3 plots but any plots and without some tedious calculations of positions)?
Is there a way to print the settings of origin, size, margins and any other relevant settings that are automatically calculated (and used) when the layout option is specified?
My guess would be that it is a bit unclear documentation.
It's a matter of taste and convenience and depends on your situation. Setting origin and size is setting the place for the (sub-)"canvas". This (sub-)"canvas" still can have some individual b,t,l,r margins. Note, margins are the space between graph border and canvas-border.
Apparently, the margins which you are setting in the multiplot layout are kept for your extra plot.
So, apparently you have to reset them, e.g. set margins 0,0,0,0. And then you are probably getting your intended plot.
I am not aware that you can extract the automatically calculated values for margins. There are no such values
listed in show var GPVAL.
Code:
### multiplot layout with manual origin and size
reset session
set xrange [0:10]
unset key
set ytics 0.5
set multiplot layout 3,1 margins 0.1,0.95,0.12,0.95 spacing 0,0
plot cos(x) axes x1y1 w l ls 3 notitle
plot sin(x) axes x1y1 w l ls 3 notitle
set key bottom center out horizontal
plot sin(x) axes x1y1 w l ls 3 notitle
set margins 0,0,0,0
set origin 0.3,0.5
set size 0.2,0.1
set xrange [1:2]
plot cos(x) axes x1y1 w l ls 3 notitle
unset multiplot
### end of code
Result:

gnuplot multiplot images in column

I'm trying to use multiplot to stack two image plots on top of one another, in a column. When I try to test this with x11 terminal, the images are produced separately, only one visible at a time. When I use the epslatex terminal, which is what I want, then the text is drawn correctly within the LaTeX document, but the EPS portion of the plot is produced as two separate pages, resulting in a figure that is missing a lower half.
Here's the multiplot section of my script:
set multiplot 2,1
set cbrange [-0.4:0.4]
set cbtics -0.4,0.2,0.4
unset xlabel
set tmargin at screen 0.95
set bmargin at screen 0.60
plot data u 1:2:3 with image notitle
set cbrange [-0.1:0.1]
set cbtics -0.1,0.05,0.1
set xlabel "$x$"
set tmargin at screen 0.50
set bmargin at screen 0.15
plot data u 1:2:3 with image notitle
unset multiplot
unset output
What results in the document is this:
I have tried enlarging the vertical size of the plotting area(per this question), but what this does is increase size of each page in the EPS file. To be clear, the product of plotting with epslatex is an EPS file containing two pages, the first with the first plot at the position that I want (near the top), and the second with the second plot at the position that I want (near the bottom).
This normally happens when you are not in multiplot mode. For me, set multiplot 2,1 gives an error message "only valid in the context of an auto-layout command". The command set multiplot layout 2,1 works with Gnuplot 5.0 and 4.6.
As a side note: This behavior can be used to produce animated gifs with set terminal gif animate, each plot command creates a new frame.

Drawing an arrow in front of one curve and behind another in gnuplot

I'm using gnuplot to draw a cone with an arrow pointing upwards through the cone's axis of symmetry. The only problem is that I can't figure out how to fit the arrow correctly into the 3D perspective of the picture. By default, the arrow is displayed behind the entire cone. If I add the "front" option to the arrow, it is displayed in front of the entire cone. But, viewed in perspective, the arrow should be in front of the back half of the cone, and behind the front half of the cone.
The obvious solution is to split the function drawing the cone into two halves and make the arrow in front of one curve and behind the other. Is there a way to do that (i.e., manually set the order in which curves and other objects are drawn)? If not, does anyone have a good workaround? (The only one I can think of is to draw the arrow manually using lines, but I'd like to avoid that if possible.)
Here is a minimal working example. I'm using a fine mesh so that the effect is clearly visible.
set arrow 1 from 0,0,0 to 0,0,1 lw 2
set isosamples 100
set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]
set zrange [0:1]
splot sqrt(x**2+y**2)
To see what's wrong with simply using the "front" option as a fix, replace the first line with:
set arrow 1 from 0,0,0 to 0,0,1 lw 2 front
Thanks in advance for any help!
Edit: I realized after posting that this can be done with multiplot. But it seems like there should be a better solution, so please let me know if you think of one.
To hide lines partially, one can usually use set hidden3d, but that does not affect arrows placed with set arrow. However it affects arrows drawn with the vectors plotting style:
set hidden3d
splot sqrt(x**2+y**2), '< echo "0 0 0 0 0 1"' with vectors
But now, one part of the arrow is hidden completely behind the surface and doesn't shine through between the surface lines. For this you can set additionally a second arrow with set arrow back ...:
set isosamples 100
set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]
set zrange [0:1]
set hidden3d nooffset
set style arrow 1 lw 2 head filled size 0.1,20,70
unset key
set arrow nohead from 0,0,0 to 0,0,1 as 1 back
splot sqrt(x**2+y**2), '< echo "0 0 0 0 0 1"' with vectors arrowstyle 1
That gives (with 4.6.4):

Smoothing out contourplot in Gnuplot?

I am trying to plot a simple contour plot (in gnuplot) for the Himmelblau's function using the following code :
f(x,y)=(((x**2)+(y)-11)**2)+(((x)+(y**2)-7)**2)
set xrange [-5:5]
set yrange [-5:5]
set contour base
set cntrparam level discrete 13.59085,25,50,100,150,300,500,1000
set table 'cont.dat'
splot f(x,y)
unset table
reset
set xrange [-5:5]
set yrange [-5:5]
unset key
p './cont.dat' w l lt -1
I get the following plot result:
There are a few problems with the plot which I wish to eliminate:
It shows some horizontal lines in the plot, I don't know why. How can I remove the horizontal lines?
The contour lines are not too smooth. How can I improve there smoothness?
I feel that both the above problems are connected but can't figure out how. Can you please help me understand and hopefully eliminate the problems?
EDIT 1 : I found the answer to question-2, i.e. improving smoothness. I could do it by increasing the isosample. But I still get a lot of horizontal lines as shown in figure below.
But how to remove these horizontal lines? I just want the contour lines for the levels specified.
Here is how you can plot only the contour lines: You must use unset surface, which plots only the contour lines, and view the plot from above with set view map. See also the 2D contour projection plot from the gnuplot demos.
Smoothing can be achieved with set isosamples, but in some way also using e.g. set cntrparam bspline and similar.
So your script becomes:
f(x,y)=(((x**2)+(y)-11)**2)+(((x)+(y**2)-7)**2)
set xrange [-5:5]
set yrange [-5:5]
set contour base
set cntrparam level discrete 13.59085,25,50,100,150,300,500,1000
set isosamples 250
unset surface
set view map
set key out
splot f(x,y)
With the result (using 4.6.3):
I was able to solve both the problems. The solution to Problem-2 I already shared in the edit-1 of question.
For Problem-1, i.e. removing the IsoLines from the contour plot, I should have left the initial blocks of data int he cont.dat files which contain the data for the isolines. Instead, I should have plotted from the Data Block 250 onwards (first 250 blocks of data were from IsoLines because of set isosample 250,250 command).

Gnuplot image on axis

I'm trying to model a certain progress through some environment. The x axis would represent the location (based on x coordinate) in the environment.
In order to make this clear, I'd like an image of the environment (based on a .png) on the x axis (the environment is rather wide and not that high, so it should look good) of my plot, basically as an xtics/x-axis label.
Do you have any suggestions on how to approach this?
Thanks in advance!
You can either plot both the image and the data in one plot command, or with multiplot. The first variant is easier, but the image is inside the plot, the other is a bit more complicated, but allows arbitrary positioning of the "axis image".
The dummy image "gradient.png" for the axis is
One plot command:
set yrange[0:1]
set xrange[0:1]
plot 'gradient.png' binary filetype=png dx=0.0015 dy=0.002 with rgbimage t '',\
x**2
The result is:
Using multiplot
set yrange[0:1]
set xrange[0:1]
set lmargin at screen 0.1
set rmargin at screen 0.98
set tmargin at screen 0.98
set bmargin at screen 0.2
set xtics offset 0,-1.5
set xlabel 'xlabel' offset 0,-1.5
set ylabel 'ylabel'
set multiplot
plot x**2
set tmargin at screen 0.2
set bmargin at screen 0.15
unset border
unset tics
unset xlabel
unset ylabel
unset key
set autoscale xy
plot 'gradient.png' binary filetype=png with rgbimage
unset multiplot
As you can see, this requires a bit more effort. To explain the details:
You must set explicit margins so that the axis image can be placed exactly below the main plot.
Before plotting the axis image, you must remove tics, labels, reset ranges to autoscale etc. (Therefore you must also set fixed lmargin and rmargin).
To plot the image itself, use the plotting style with rgbimage.
You must fine-tune the xtics and xlabel offset, as well as the marings.
The resulting image is:

Resources