Reputation: 3754
I often plot noisy data along with a model. The residuals are shown in a bottom panel:
set colors classic
set samp 20000
set table $data
plot '+' u 1:(y=10*(sin(10*$1))):(y-invnorm(rand(0))) w e
unset table
set multiplot layout 2,1
plot $data us 1:($2+$3):3 w p pt 7 ps 0.5 t "noisy data", $data us 1:2 w l lc 3 t "model"
plot $data us 1:3 w p pt 7 ps .5 t "noise"
unset multiplot
However, this is not interactive anymore. After zooming one plot will be lost. (Matplotlib has here shared axis.)
My current approach is also not satisfying, but works at least if zooming only horizontally.
set autoscale y2fix
set y2range [-5:25]
plot [][-30:] $data us 1:($2+$3):3 w p pt 7 ps 0.5 t "noisy data", $data us 1:2 w l lc 3 t "model", $data us 1:3 w p pt 7 ps .5 t "noise" axis x1y2
Upvotes: 1
Views: 401
Reputation: 15118
Commenting from the future to note that gnuplot version 6 supports replot
to reproduce an entire previous multiplot and allows mousing within an active multiplot. However, if the component plots within a multiplot have disparate axis ranges then pan/zoom may not do what you expect.
Upvotes: 0
Reputation: 3754
Based on the suggestion by @theozh to redraw everything in a while
loop, this version reacts on mouse click. Each left click redraws the multiplot.
set colors classic
set samp 20000
set table $data
plot '+' u 1:(y=10*(sin(10*$1))):(y-invnorm(rand(0))) w e
unset table
cond=1; while(cond) {
set yrange [*:*]
set multiplot layout 2,1 upwards
unset label 1
plot $data us 1:3 w p pt 7 ps .5 t 'noise'
set label 1 at graph 0.01, graph 0.95 "middle click = stop" boxed front
plot $data us 1:($2+$3):3 w p pt 7 ps 0.5 t 'noisy data', $data us 1:2 w l lc 3 t 'model'
unset multiplot
pause mouse button1,button2
cond = MOUSE_KEY != 2 # exit on middle click
}
Starting rectangular zoom with right click and finishing it with left click, it appears still smooth, though not as speedy as the version with axis x1y2
.
Since bind
does unfortunately not work for mouse events, pause
and while
loop is used instead to emulate this behaviour.
Upvotes: 3
Reputation: 25843
Unfortunately, gnuplot cannot have interactive multiplots (maybe in the future?). I also would love to see mouse coordinates in a multiplot. Apparently, you can only zoom when you have a single plot. Therefore, the following strange workaround might be helpful to you.
Usage:
You might also use the gnuplot-builtin bindings "p" and "n" for "previous zoom" and "next zoom".
Type show bind
to see all key-bindings.
The following could be a starting point for further optimization and tweaking to your exact needs.
Code:
### workaround for interactive multiplot
reset session
set print $Data
do for [i=1:200] {
print sprintf("%.3g %.3g %.3g",x=i/20., sin(x), rand(0)*0.2-0.1)
}
set print
Stop = 0
myPlot = 0
myAutoscale = 0
myLastPlot = 0
bind "x" "Stop = 1"
bind "0" "myPlot = 0"
bind "1" "myPlot = 1"
bind "2" "myPlot = 2"
bind "a" "myAutoscale = 1"
set style textbox opaque
set label 1 at graph 0.01, graph 0.95 "Press key:\nx=stop\n0=mulitplot\n1=Plot1\n2=Plot2\na=autoscale" boxed front
Plot1 = 'plot $Data u 1:($2+$3) w p pt 7 ps 0.5 lc rgb "red" ti "Data", \
"" u 1:2 w l lc rgb "blue" ti "Model"'
Plot2 = 'plot $Data u 1:3 w p pt 7 ps 0.5 lc rgb "blue" ti "Noise"'
set autoscale xy
PXmin = 0; PXmax = 10
P1Ymin = -1.2; P1Ymax = 1.2
P2Ymin = -0.3; P2Ymax = 0.3
while (!Stop) {
if (myPlot == 0 || myAutoscale==1) {
set multiplot layout 2,1
# first plot
if (myLastPlot) { PXmin = GPVAL_X_MIN; PXmax = GPVAL_X_MAX }
if (myLastPlot==1) { P1Ymin = GPVAL_Y_MIN; P1Ymax = GPVAL_Y_MAX }
if (myLastPlot==2) { P2Ymin = GPVAL_Y_MIN; P2Ymax = GPVAL_Y_MAX }
set xrange[PXmin:PXmax]
set yrange[P1Ymin:P1Ymax]
if (myAutoscale) { set autoscale xy }
@Plot1
PXmin = GPVAL_X_MIN; PXmax = GPVAL_X_MAX
P1Ymin = GPVAL_Y_MIN; P1Ymax = GPVAL_Y_MAX
# second plot
set xrange[PXmin:PXmax]
set yrange[P2Ymin:P2Ymax]
if (myAutoscale) { set autoscale xy }
@Plot2
P2Ymin = GPVAL_Y_MIN; P2Ymax = GPVAL_Y_MAX
myAutoscale = 0
myLastPlot = 0
unset multiplot
}
if (myPlot == 1) {
set xrange[PXmin:PXmax]
set yrange[P1Ymin:P1Ymax]
@Plot1
myLastPlot=1
}
if (myPlot == 2) {
set xrange[PXmin:PXmax]
set yrange[P2Ymin:P2Ymax]
@Plot2
myLastPlot=2
}
myPlot = -1
pause 0.1 # not sure whether this is necessary or has some advantage
}
### end of code
Result:
Multiplot
Multiplot (zoomed in):
Upvotes: 3