Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GNUplot Autoscale set xrange equal to yrange

Tags:

plot

gnuplot

I'm using GNUplot to plot orbits from a datafile. I want to use autoscale xy so that the GNUplot script does not need to edited depending on the data. However, when I plot, autoscale doesn't set the xrange to be the same as yrange. This makes the orbits look "squashed".

I've tried using set size square and set size ratio -1 How to set equal scale's length in gnuplot.

But this didn't work.

Is there anyway to force autoscale to make the x and y ranges equal?

Thanks!

like image 672
Rohan Avatar asked Nov 18 '14 15:11

Rohan


1 Answers

No, there is no option to autoscale x- and y-range to the same values. Here is a solution, how you can do this with some tricks.

If you want to keep gnuplot's extending of the ranges to the next tics, you can do it as follows:

You must first plot once using the unknown terminal. This saves the x- and y-ranges in the gnuplot variables GPVAL_X_MIN, GPVAL_X_MAX, GPVAL_Y_MIN and GPVAL_Y_MAX. Then you set the ranges and replot:

set terminal push # save current terminal
set terminal unknown
plot 'datafile'
set terminal pop # restore previous terminal

min = (GPVAL_Y_MIN < GPVAL_X_MIN ? GPVAL_Y_MIN : GPVAL_X_MIN)
max = (GPVAL_Y_MAX > GPVAL_X_MAX ? GPVAL_Y_MAX : GPVAL_X_MAX)

set xrange[min:max]
set yrange[min:max]
set size ratio -1

replot

The push/pop stuff is required only if you want to keep the initial terminal settings.

To make this reusable, e.g. for use with multiplot, you can wrap all those commands inside a string and call eval on it:

autoscale_xy(datafile) = \
    "set terminal push; set terminal unknown; set autoscale;".\
    "plot '".datafile."'; set terminal pop;".\
    "min = (GPVAL_Y_MIN < GPVAL_X_MIN ? GPVAL_Y_MIN : GPVAL_X_MIN);".\
    "max = (GPVAL_Y_MAX > GPVAL_X_MAX ? GPVAL_Y_MAX : GPVAL_X_MAX);".\
    "set xrange[min:max]; set yrange[min:max];"
...

files = "first second third fourth"
do for [f in files] {
    eval(autoscale_xy(f))
    plot f
}

Another option would be to use stats to compute the maximum and minimum x- and y-values and set the ranges accordingly:

stats 'datafile' using 1:2 nooutput
min = (STATS_min_y < STATS_min_x ? STATS_min_y : STATS_min_x)
min = (STATS_max_y > STATS_max_x ? STATS_max_y : STATS_max_x)

sc = 1.05
set xrange[sc*min:sc*max]
set yrange[sc*min:sc*max]
set size ratio -1

plot 'datafile'
like image 107
Christoph Avatar answered Nov 14 '22 19:11

Christoph