Search code examples
formattinggnuplot

Can't get upper axis values through linking with lower axis in gnu plot


I am trying to link the upper axis with the lower axis in gnu plot, that is print out values on the upper axis given a relationship between the upper axis quantities and the lower axis ones. The relationship between them is

x2 = 2*c**2/(2*x1**2-c**2) with c=1.548458. The following should be sufficient

set xlabel "Quantity lower"
set xtics nomirror
set x2label "Quantity Upper"
set x2tics nomirror
set link x2 via 2*(2*1.548458)**2/(2*x**2-(2*1.548458)**2) inverse sqrt((2*1.548458)**2*(2+x)/2/x)

#set link x via 1239.8/x inverse 1239.8/x

set ylabel "Quantity y"
set ytics 0.2
set samples 400
Spectrum(x) = exp(-(x-500)**2/(400))

set xrange[30:2000]

set format x2 "%.2f"
plot Spectrum(x) w l title "Spectrum"

I've also log formatted the x axis via

set logscale x set format x "10^{%L}"

but regardless of whether I include the log formatting I am unable to get any meanginful values printed out on the upper axis. (The function for y is for illustrative purposes only, the value for y in my actual script relies on reading in data from a file)

I'd like to print out values on the upper axis for say two values of x=100, 1000 say. Thanks!


Solution

  • I don't know how to set tics automatically. But at least you can set them explicitly.

    You want to set x2 tics at given x1 values. As the set x2tics command takes tic positions in x2 coordinates, you can convert the given x1 values into x2 values. I have modified your script to illustrate what I mean:

    set xlabel "Quantity lower"
    set xtics nomirror
    set x2label "Quantity Upper"
    set x2tics nomirror
    
    # avoid warnings by setting the xrange before linking the axes
    set xrange[30:2000]
    
    # setup the link functions
    c = 1.548458 # or 2*1.548458 ? 
    link_x1_x2(x) = 2*c**2/(2*x**2-c**2) 
    link_x2_x1(x) = c*sqrt((2+x)/(2*x))
    
    set link x2 via link_x1_x2(x) inverse link_x2_x1(x)
    
    # you want to set x2 tics at x1 = 100 and x1 = 1000
    # check the corresponding x2 values 
    print "x2 = x1( 100) = ", link_x1_x2(100)
    print "x2 = x1(1000) = ", link_x1_x2(1000)
    
    # set the tics with formatted tic labels as an example
    set x2tics ("a: %.2e" link_x1_x2(100), "b: %.2e" link_x1_x2(1000))
    
    set ylabel "Quantity y"
    set ytics 0.2
    set samples 400
    Spectrum(x) = exp(-(x-500)**2/(400))
    
    
    # this seems not to work with explicit tics
    # set format x2 "%.2f"
    
    plot Spectrum(x) w l title "Spectrum"
    

    This is the output:

    x2 axis linked to x1 axis

    If you need logarithmic axes and the set link command does not work, you can replace it by setting the x2axis properties explicitly with set x2range. See the modified script:

    set xlabel "Quantity lower"
    set xtics nomirror
    set x2label "Quantity Upper"
    set x2tics nomirror
    
    
    # setup the link functions
    c = 1.548458 # or 2*1.548458 ?
    link_x1_x2(x) = 2*c**2/(2*x**2-c**2) 
    link_x2_x1(x) = c*sqrt((2+x)/(2*x))
    
    xmin = 30
    xmax = 2000
    set xrange[xmin:xmax]
    set x2range[link_x1_x2(xmin):link_x1_x2(xmax)]
    
    set logscale x 
    set logscale y 
    set logscale x2
    
    # set the tics at x1 = 100 and x1 = 1000
    set x2tics ("a: %.2e" link_x1_x2(100), "b: %.2e" link_x1_x2(1000))
    
    set ylabel "Quantity y"
    #set ytics 0.2 # this must be improved for logarithmic plotting
    set samples 400
    Spectrum(x) = exp(-(x-500)**2/(400))
    
    plot Spectrum(x) w l title "Spectrum"
    

    This is the result:

    manual linkage

    Note that the drop of the function at about x1 = 1000 is caused by numerical underflow.


    Update:

    As we did not get the automatic linking to work for logarithmic plots, I would add minor tics manually. See help set xtics for details.

    # just for a check
    set grid mxtics
    # set the tics at x1 = 100 and x1 = 1000
    # set minor tics in between (at level 1)
    set x2tics ("a: %.2e" link_x1_x2(100), \ 
                "" link_x1_x2(200) 1,      \ 
                "" link_x1_x2(300) 1,      \ 
                "" link_x1_x2(400) 1,      \ 
                "" link_x1_x2(500) 1,      \ 
                "" link_x1_x2(600) 1,      \ 
                "" link_x1_x2(700) 1,      \ 
                "" link_x1_x2(800) 1,      \ 
                "" link_x1_x2(900) 1,      \ 
                "b: %.2e" link_x1_x2(1000))
    

    Now we have this result:

    add minor tics