multiplot of isolines and points creates two axis frames - gnuplot

I've created a multiplot containing an isoline plot f(x,y) and a point, (0,0) on the zero level set of the isoline plot. Unfortunately the point plot appears to create a second axis frames as shown below
f(x,y)=2*x**2 - x + 2*y**2 - y - 2
set multiplot
set xrange [-3:3]
set yrange [-3:3]
set isosamples 250
set contour
unset surface
set view map
set key out
set cntrparam levels incremental 0,1,5
splot f(x,y)
plot "< echo '1 1'"
set nomultiplot
What can I do to solve this problem?
Update
A bit more context. In the larger problem I am using multiplot to superimpose two isoline plots, as hinted below. Both isoline plots share a common axis frame.
...
set cntrparam levels incremental 0,1,5
splot f(x,y)
set cntrparam levels discrete 0
g(x,y)=(x - 1)**2 + y**2 - 1
splot g(x,y)

Unless there are additional requirements that mandate use of multiplot, the simplest solution is to draw your single point as a label instead. The label comes with a point for free. You only want the point, so the label text is an empty string.
If this was a proxy question for a more complicated requirement, please edit the question to give more detail.
f(x,y)=2*x**2 - x + 2*y**2 - y - 2
set label 1 "" at 1,1,0 point pt 7 lc "blue"
set xrange [-3:3]
set yrange [-3:3]
set isosamples 250
set contour
unset surface
set view map
set key out
set cntrparam levels incremental 0,1,5
splot f(x,y) with lines
Edit
The multiplot version:
f(x,y)=2*x**2 - x + 2*y**2 - y - 2
g(x,y)=(x - 1)**2 + y**2 - 1
set label 1 "" at 1,1,0 point pt 7 lc "blue"
set xrange [-3:3]
set yrange [-3:3]
set isosamples 250
set contour
unset surface
set view map
set multiplot
set cntrparam levels incremental 0,1,5
set key out top
splot f(x,y) with lines
set cntrparam levels discrete 0
set key out bottom
splot g(x,y) with lines
unset multiplot

This would be my suggestion:
you don't need multiplot (I would use it only if absolute necessary)
plot the contour data into a table and instead of 3D splot and "set view map" use a 2D plot. Because after set contour you cannot plot a single datapoint as non-grid data.
there are a lot of ways to plot a single data point. My preference would be without system call.
you might want to set size ratio -1, then a circle appears as a circle
Update:
Here is the extended example after you mentioned your second contour function g(x,y).
Just to mention the differences between a multiplot solution and a single plot solution:
Script (multiplot): (with fixed margins and legend box positions relative to screen)
easy handling of the legend entries and boxes (but manual positioning if more than 2)
you need to set fixed margins to get reliable overlap independent of the legend. At least, fixed top/bottom margins are enough if you set size ratio -1. Additionally, you can set the legend to a fixed position relative to the screen.
I recommended to unset border, tics and labels for the second plot, otherwise these elements get a slight "bold" appearance if you plot them several times on top of each other (you will notice if you compare the numbers on Ethan's first and second plot)
zooming is not possible with multiplot in interactive terminals, e.g. wxt, qt
requires another multiplot if you want to plot single/multiple points from another file/datablock
so far, I haven't found out how to freely control the color of the contour lines. But I'm sure there is a way.
### plot several contour plots and add a single point (multiplot)
reset session
f(x,y) = 2*x**2 - x + 2*y**2 - y - 2
g(x,y) = (x-1)**2 + y**2 - 1
set xlabel "x-label"
set xrange [-3:3]
set ylabel "y-label"
set yrange [-3:3]
set samples 100
set isosamples 100
set contour
unset surface
set view map
set size ratio -1
set multiplot
xPos = 0.95
set key at screen xPos,0.9 title "Main title" font ",12"
set bmargin screen 0.15
set tmargin screen 0.92
set cntrparam levels incremental 0,1,5
splot f(x,y) w l
set cntrparam levels discrete 0
unset border
unset tics
unset xlabel
unset ylabel
set key at screen xPos,0.5 notitle
splot g(x,y) w l
set key at screen xPos,0.35 notitle
plot '+' u (1):(1) every ::::0 w p pt 7 lc "red" ti "You are here"
unset multiplot
### end of script
Result:
Script (single plot):
zooming possible in interactive terminals, e.g. wxt, qt
extra tables for contours
a bit more effort with the legend (but auto positioning)
easy customization of contour line color
For the single plot, the extraction of the contour level labels is a bit tricky and needs some explanations.
The contour data in the datablocks looks like this:
# Surface 0 of 1 surfaces
# Curve title: "f(x,y)"
# Contour 0, label: 5
-1 -1.15789 5
-1.15789 -1 5
-1.54386 -0.333333 5
...
-0.333333 -1.54386 5
-1 -1.15789 5
# Contour 1, label: 4
-0.333333 -1.38596 4
...
The data is separated by two empty lines. So, you can address the subblocks by using index (check help index).
So, now, after skipping the first 5 lines, you need to extract the contour label value from each the first line (header) of each (sub)block from the 5th column. For this, you need to tell gnuplot that # is not a comment character anymore (check help datafile commentschars).
Furthermore, the legend entry for the functions names are realized by keyentries (check help keyentry) with a fully transparent point according to the color scheme 0xaarrggbb where alpha is `0xff´.
### plot several contour plots and add a single point (single plot)
reset session
f(x,y) = 2*x**2 - x + 2*y**2 - y - 2
g(x,y) = (x-1)**2 + y**2 - 1
set xlabel "x-label"
set xrange [-3:3]
set ylabel "y-label"
set yrange [-3:3]
set samples 100
set isosamples 100
set contour
unset surface
set table $ContourF
set cntrparam levels incremental 0,1,5
splot f(x,y)
set table $ContourG
set cntrparam levels discrete 0
splot g(x,y)
unset table
set size ratio -1
set key noautotitle left at graph 1.05,1 title "Main title" font ",12"
set datafile commentschar ''
plot keyentry w p lc rgb 0xff123456 ti "f(x,y)", \
for [i=0:*] $ContourF u 1:2:3 skip 5 index i w l lc i ti columnhead(5), \
keyentry w p lc rgb 0xff123456 ti "g(x,y)", \
for [i=0:*] $ContourG u 1:2:3 skip 5 index i w l lc "blue" ti columnhead(5), \
'+' u (1):(1) every ::::0 w p pt 7 lc "red" ti "You are here"
### end of script
Result:

Related

gnuplot: bar charts visualization

My gnuplot script plot a bar graph for 2D data either in monochrome or color format:
set term pngcairo size 800,600
set termoption noenhanced
set tics font "Helvetica,10"
#set xtics noenhanced
set ylabel "Fraction, %"
set xlabel "H-bond donor/aceptor, residue"
set yrange [0:1]
set ytics 0.1
set grid y
set key off
set boxwidth 0.9
set style fill solid 0.5
# TWO OPTIONS FOR BAR VISUALISATIONS!! NB: ADD HERE TRIGGER FROM COLOR_DATA TRIGGER
# 1 - use it with non-colored bars"
#plot "\$data" using 0:2:xtic(1) with boxes, "" using 0:2:2 with labels offset 0,1
# 2 - or use it with colored bars:
plot \$data using 0:2:3:xtic(1) with boxes lc rgb var, \
'' using 0:2:2 with labels offset 0,1
The problem when I have just one bar, one the graph it occupiers all the graph on X:
Would it be possible to set some minimum dimension for the bars to make the dimensions of a single bar similar for a situations with two bars, for instance:
My understanding is the following: if you have only one box:
maybe gnuplot tries to autoscale and the automatic boxwidth is small relative to the autorange (hence just a thin line).
if you set a certain boxwidth, autoscale with scale to the given boxwidth (hence the graph filled with the box).
you could set a fixed xrange, but then you are loosing the benefits of autoscale. Instead you can use set offets (check help offsets).
if you have more than 1 box autoscale will work.
Script:
### boxwidth with boxes style
reset session
$Data1 <<EOD
1 Abc
EOD
$Data2 <<EOD
1 Abc
2 Xyz
EOD
set style fill solid 0.3
set key out
set rmargin screen 0.7
set yrange[0:]
set ytics 0.5
set multiplot layout 4,1
plot $Data1 u 0:1:xtic(2) w boxes ti "No special settings"
set boxwidth 0.9
plot $Data1 u 0:1:xtic(2) w boxes ti "set boxwidth"
set offsets 1,1,0,0
plot $Data1 u 0:1:xtic(2) w boxes ti "set offsets"
set offsets 0,0,0,0
plot $Data2 u 0:1:xtic(2) w boxes ti "more than 1 box"
unset multiplot
### end of script
Result:

Align ylabel in gnuplot multiplot

Is there a way to align vertically the y labels of in gnuplot's multiplot so that they are below each other? The problematic example is below (the red line is annotation showing the problem):
set xrange[0:10]
set multiplot layout 2,1 margins 0.1,0.95,0.1,0.95 spacing 0,0
set ylabel "y1\nlabel"
set ytics
set format y "%.2f"
plot -1000*cos(x)**2 w l lt 4 lw 2
set ylabel "y2\nlabel"
set format y "%.1f"
plot cos(x) w l lt 5 lw 2
unset multiplot
which generates:
And I would like to automatically position the labels such, that the red annotated line "touches the same text". Note that I am really interested in automatic way or more correct way that a workaround using a trial and error with set ylabel "lable" offset -x,0
As you already noted, you can set an offset to the x- or y-label (check help xlabel), however, no absolute position.
This you can do with setting your own label. You can set the position relative to the screen and/or relative to the graph. gnuplot keeps these values for the second plot, no need to specify again. Check help label.
Check the following example:
Code:
### align ylabels in multiplot
reset session
set xrange[0:10]
set multiplot layout 2,1 margins 0.15,0.95,0.1,0.95 spacing 0,0
set format x ""
unset ylabel
set label 1 "y1\nlabel" at screen 0.02, graph 0.5 center rotate by 90
set ytics 200
set ytics add ("" -1000) # remove -1000
set format y "%.2f"
set grid x,y
plot -1000*cos(x)**2 w l lt 4 lw 2
set format x
set label 1 "y2\nlabel"
set ytics 0.4
set format y "%.1f"
plot cos(x) w l lt 5 lw 2
unset multiplot
### end of code
Result:

How to move and manage overlapping of x ticks with axis in Gnuplot

I am trying to plot an inlet graph which is shown in Figure. Being an inlet graph it is needed to show x tics and y ticks of relatively big sizes for clear visibility. But when I increase the fonts as,
set xtics font ", 40"
tics overlaps with axis. I increased the plot size set term png size 1000, 1000 but still the issue persists. Kindly suggest if there is a way to move the tics below or to a desired position in graph.
Edit:
The gnuplot script looks like this,
set term png size 1000, 1000
set output "b_vs_N.png"
set style fill solid
set style circle radius 0.001
FIT_LIMIT=1.e-14
set yrange [0.15:0.25]
set style fill solid
set style circle radius 0.001
set xtics 10
set ytics 0.03
set border 15 back lw 6
set xtics font ", 40"
set ytics font ", 22"
set ylabel "b" enhanced font "1 {,40}"
set xlabel "N_i" font "1 {,40}"
set lmargin 12
set bmargin 4
set palette model HSV
set palette rgb 3,2,2
set palette maxcolors 12
set view map
AA(x)=a+b*x+c*x**2
fit AA(x) "data.txt" using 1:2 via c, b, a
plot "data.txt" using 1:2 lt 1 pt 11 ps 2.0 lc rgb "black" notitle, AA(x) w lines lw 2 lc rgb "sienna1" notitle
Your example is uncomplete without code and therefore difficult to reproduce. Please check help xtics. There is the option offset.
Maybe the following example helps to solve your issue.
In the example below no special offset seems to be necessary, i.e. offset 0,0, but you can shift and adjust the labels in x and y direction.
Code:
### tic label offset
reset session
set multiplot
plot sin(x)/x
set origin 0.07, 0.6
set size 0.3,0.3
set xrange [0:10]
set xtics 5 out font ",20" offset 0,0
plot x**2
unset multiplot
### end of code
Result:

gnuplot curve from file and parametric sphere

I am trying to plot in a 3d space a curve coming from a file and a sphere made with parametric entries.
The idea is to plot the planet Earth and the orbit of a satellite.
The orbit is defined in a file x y z and gnuplot commands are simply
splot 'file.txt' u 1:2:3 title 'Orbit element 1' with lines
Orbit satellite :
I found a script to plot the Earth
#color definitions
set border lw 1.5
set style line 1 lc rgb '#000000' lt 1 lw 2
set style line 2 lc rgb '#c0c0c0' lt 2 lw 1
unset key; unset border
set tics scale 0
set lmargin screen 0
set bmargin screen 0
set rmargin screen 1
set tmargin screen 1
set format ''
set mapping spherical
set angles degrees
set xyplane at -1
set view 56,81
set parametric
set isosamples 25
set urange[0:360]
set vrange[-90:90]
r = 0.99
splot r*cos(v)*cos(u),r*cos(v)*sin(u),r*sin(v) with lines linestyle 2,'world.dat' with lines linestyle 1
unset parametric
Unfortunately, I am not able to mix splot wiht the data file and the splot with the parametric.
Any suggestions more than welcome!
Thanks
In order to generate the plot below, I used the data linked in this blog post. Now, if we want to combine several data sources into one plot, we will need to convert one or the other into a common system of coordinates. If the satellite data is in Cartesian x,y,z coordinates, perhaps the easiest solution would be to convert the world map into Cartesian system as well.
This could be done as shown below. The parameter R denotes the radius of the sphere on the surface of which Gnuplot draws the world map. It should be slightly larger than r so that hidden3d works. The columns in the world_110m.txt file have the meaning of longitude (first column) and latitude (second column), therefore the conversion is given as (R*cos($1)*cos($2)):(R*sin($1)*cos($2)):(R*sin($2)). In the file input.pnts.dat, I just generated coordinates of points on an ellipse with a=1.6 and b=1.2 rotated around the x axis by 45 degrees (counterclockwise). For real satellite data, one would need to rescale the coordinates by dividing by the radius of Earth, i.e., use ($1/Re):($2/Re):($3/Re) instead of 1:2:3, where Re denotes the radius in whichever units your data is (probably meters, judging by the first plot in your question).
set terminal pngcairo
set output 'fig.png'
set xr [-2:2]
set yr [-2:2]
set zr [-2:2]
#color definitions
set border lw 1.5
set style line 1 lc rgb '#000000' lt 1 lw 2
set style line 2 lc rgb '#c0c0c0' lt 2 lw 1
unset key; unset border; set tics scale 0
set format ''
set angles degrees
set xyplane at -1
set view 56,81
set lmargin screen 0
set bmargin screen 0
set rmargin screen 1
set tmargin screen 1
set parametric
set isosamples 25
set urange[0:360]
set vrange[-90:90]
r = 0.99
R = 1.00
set hidden3d
#since we are using Cartesian coordinates, we don't want this
#set mapping spherical
splot \
r*cos(v)*cos(u),r*cos(v)*sin(u),r*sin(v) with lines linestyle 2, \
'world_110m.txt' u (R*cos($1)*cos($2)):(R*sin($1)*cos($2)):(R*sin($2)) w l lw 2 lc rgb 'black', \
'input.pnts.dat' u 1:2:3 w l lw 2 lc rgb 'red'
This then gives:

Histogram using gnuplot with multiple y-axes

I could not find a solution to the following issue I am facing. All SO questions on multi-axis talk about line plots, but I am looking for histograms.
The y-range for the bars are different, so one set of bars are not really seen because of the scale. Here is the data:
Metric A B
M1 0.613416301 0.543734744
M2 0.000195961 0.000100190
Here is the MWE:
reset
set term postscript eps size 5.5,4.5 enhanced color font 'Arial-Bold' 25
set out 'histplot.eps'
set key right
set style histogram cluster gap 2
set style data histograms
set style fill pattern 1.00 border
set y2range [0.0001:0.0002]
plot 'histplot.dat' using 2 ti col, '' u 3:xticlabels(1) ti col
quit
This is the sample output (one set of bars over M2 is not seen):
What I prefer is to have a second y-axis (to the right side of the plot) with a range appropriate to the second row of my data file. Is this possible? Any help is greatly appreciated.
Normally you can plot severyl histograms beneath each other using newhistogram. However, it seems like this is buggy when using patterns as fillstyle:
reset
set style histogram cluster gap 1
set style data histograms
set style fill pattern 1.00 border
set yrange [0:*]
set ytics nomirror
set y2range [0:*]
set y2tics
set key right autotitle columnheader
plot 'histplot.dat' u 2 every ::::0, '' u 3:xtic(1) every ::::0,\
newhistogram lt 1 at 1,\
'histplot.dat' u 2 every ::1::1 axes x1y2, '' u 3:xtic(1) every ::1::1 axes x1y2
Alternatively you can use multiplot and plot the two histograms directly beneath each other:
reset
set style histogram cluster gap 1
set style data histograms
set style fill pattern 1.00 border
set yrange [0:*]
set ytics nomirror
set multiplot layout 1,2
set rmargin at screen 0.5
set lmargin 9
unset key
plot 'histplot.dat' using 2 every ::::0 ti col, '' u 3:xticlabels(1) every ::::0 ti col
set rmargin 9
set lmargin at screen 0.5
unset ytics
set y2range [0:*]
set y2tics
set key right
plot '' using 2 every ::1::1 axes x1y2 ti col, '' u 3:xtic(1) every ::1::1 axes x1y2 ti col
unset multiplot
If you don't want the separating black line, you can use set border 7 for the first and set border 13 for the second plot.

Categories

Resources