Search code examples
gnuplot

gnuplot: force y2 axis tics on y tics position


inspired from the set link in another answer i want to plot a graph and show different scale axis.

set grid mytics
set xrange[1:5]  
set yrange[0:3]
set y2range[0:30]
set xlabel "a"   
set ylabel "b"  
set ytics 
set y2label "c"
set mytics 2

ca = 0.05
cb = 0.5

f(x) = sin(x*pi/180)*cb *1000
i(x) = asin(x/1000 / cb )/pi*180
set link y2 via f(y) inverse i(y)

pl asin(ca /x)/pi*180 title "a"

it draws the plot and the axis as expected but what i want is that the tics on the y2 axis are exact on the ytics (although they will be non round numbers)


Solution

  • There is no option to put e.g. 6 equally distributed tics on an axis (like it would be done with set my2tics 7). But you can add the tics manually because you know the function range.

    First you need to clear all automatic y2tics with

    set y2tics (f(0))
    

    And then you can set all minor and major tics in a loop:

    do for [i=0:6] {
        set y2tics add (f(i/2.0))
        set y2tics add ('' f(i/2.0 + 0.25) 1)
    }
    

    Note, that looping with a float increment doesn't work.

    So your complete script looks like this:

    reset
    set grid mytics
    set xrange[1:5]  
    set yrange[0:3]
    set y2range[0:30]
    set xlabel "a"   
    set ylabel "b"  
    set ytics nomirror
    set y2label "c"
    set mytics 2
    
    ca = 0.05
    cb = 0.5
    
    f(x) = sin(x*pi/180)*cb *1000
    i(x) = asin(x/1000 / cb )/pi*180
    set link y2 via f(y) inverse i(y)
    
    set format y2 '%.2f'
    set y2tics (f(0)) # clear all automatic y2tics
    do for [i=0:6] {
        set y2tics add (f(i/2.0))
        set y2tics add ('' f(i/2.0 + 0.25) 1)
    }
    
    pl asin(ca /x)/pi*180 title "a"
    

    with the result:

    enter image description here

    There is a way to set the y2tics independent of the yrange as long as the number of major tics is known. First you plot with the unknown terminal, after which you can access the yrange value as the variables GPVAL_Y_MIN and GPVAL_Y_MAX. Unfortunately, one cannot access the number of tics of an axis:

    ...
    set link y2 via f(y) inverse i(y)
    
    set terminal push # save current terminal
    set terminal unknown
    pl asin(ca /x)/pi*180 title "a"
    
    num_tics = 7
    set format y2 '%.2f'
    set y2tics (f(GPVAL_Y_MIN)) # clear all automatic y2tics
    Y0 = GPVAL_Y_MIN
    DY = (GPVAL_Y_MAX - GPVAL_Y_MIN)/(num_tics-1)
    do for [i=0:(num_tics-1)] {
        set y2tics add (f(Y0+i*DY))
        set y2tics add ('' f(Y0+(i+0.5)*DY) 1)
    }
    
    set terminal pop # restore terminal
    replot