2

I'm doing a large number of plots using gnuplot. As the data range (for both x and y axis) is variable for each plot, I need to let gnuplot auto set both range and tics. However, I need to place a defined grid under the plot, with horizontal lines each 1/8 unit and verical lines 1/4 unit. As I let gnuplot decide where to place tics, I don't know the distance (in units) between two tics and hence, I don't know the number of subdivisions that I should made in m{x|y}tics to have the desired output.

E.g.: If I have a ytic every two units, I need to "set mytics 8". If I have a ytic every unit, I need to "set mytics 4".

So, there is someway to obtain the distance between auto-placed tics? Or even the number of plotted tics?

Isma
  • 127
  • 6

1 Answers1

6

To get the distance between auto-placed tics, use the following code (save as ticstep.gp):

xr = abs(max_value - min_value)
power = 10.0 ** floor(log10(xr))
xnorm = xr / power # approximate number of decades
posns = 20.0 / xnorm;

if (posns > 40) {
  tics = 0.05
} else {
  if (posns > 20) {
    tics = 0.1
  } else {
    if (posns > 10) {
      tics = 0.2
    } else {
      if (posns > 4) {
        tics = 0.5
      } else {
        if (posns > 2) {
          tics = 1
        } else {
          if (posns > 0.5) {
            tics = 2
          } else {
            tics = ceil(xnorm)
          }
        }
      }
    }
  }
}
ticstep = tics * power

This ought to be equivalent to the internal gnuplot-code to determine the ticstep (see axis.c, line 677.

To get the ticstep only, you can use stats to get the respective data values:

stats 'file.txt' using 1 noutput
max_value = STATS_max
min_value = STATS_min
load 'ticstep.gp'
print ticstep

To get the number of plotted tics you need the autoextended axis limits (unless you use set autoscale fix). For this you can plot with the unknown terminal to get e.g. GPVAL_Y_MAX and GPVAL_Y_MIN:

set terminal push # save current terminal
set terminal unknown
plot 'file.txt' using 1
set terminal pop # restore terminal
max_value = GPVAL_Y_MAX
min_value = GPVAL_Y_MIN
load 'ticstep.gp'

print sprintf('ticstep = %f', ticstep)
numtics = int((xr / ticstep) + 1)
print sprintf('numtics = %d', numtics)
Christoph
  • 47,569
  • 8
  • 87
  • 187
  • 1
    with ticstep.gn you saved my day. Again :) It helped me to generate custom ytics – taiko Jul 18 '17 at 18:09
  • @taiko Great that it helped you – Christoph Jul 18 '17 at 18:12
  • yeah. As the asker I needed to generate more plots with different data ranges. Autoscale wasn't working to my satisfaction. With STATS_min, STATS_max and a bit finetunnig of your ticstep function I was able to do " set ytics STATS_min,ticstep, STATS_max ". – taiko Jul 18 '17 at 18:34
  • @Christoph, just for completeness, be aware that `floor(log10(xr))` does not always give you the expected order of magnitude (see https://stackoverflow.com/q/55130265/7295599). Well, it's not tragic, in worst case you get too many tic labels ;-) – theozh Mar 31 '19 at 07:54