gnuplot: how to set custom non linear scales

后端 未结 2 983
迷失自我
迷失自我 2020-12-18 04:06

is there any possibility for using non linear scales with self defined break of slope points? For example: i want the half of the y-scale shows the range [0:1] and the other

相关标签:
2条回答
  • 2020-12-18 04:44

    You have a couple of options to accomplish that kind of plot. I will use these sample data:

    0 0
    1 0.5
    2 0.6
    3 1
    4 1.5
    5 0.5
    6 2.5
    7 5
    8 2
    

    Multiplot method

    Here you just make two plots of the same data on top of each other. Note that where the data cross the border of the plots there is a joint in the line (if you plot a line).

    This is a little more complicated than the mapping method below.

    #!/usr/bin/env gnuplot
    
    reset
    
    set terminal pdfcairo enhanced color lw 3 size 3,2 font 'Arial,14'
    set output 'output.pdf'
    
    set style data linespoints
    
    set title 'my plot'
    set key top left
    
    set multiplot layout 2,1
    
    ### first (top) plot
    # play with margins to ensure top and bottom plots are same size
    set bmargin 0
    set tmargin 2.5
    # also that left margin is same with/without y label
    set lmargin 6
    
    set yrange [1:5]
    
    unset xtics
    set ytics 1 out scale 0.5 nomirror
    
    # remove bottom line of border
    set border 14
    
    plot 'data.dat' pt 7 title 'my data'
    
    ### second (bottom) plot
    unset title
    
    # set margins to match first plot
    set bmargin 2.5
    set tmargin 0
    
    set yrange [0:1]
    
    # this offset along with the label offset compresses the bottom whitespace
    set xtics out scale 0.5 nomirror offset 0,0.4
    
    # create and place labels where they will be visible
    set xlabel 'x label' offset 0,0.8
    set ylabel 'y label' offset 1,3
    
    # remove top line of border
    set border 11
    plot 'data.dat' pt 7 notitle
    
    unset multiplot
    
    reset
    

    Result:

    enter image description here

    Mapping method

    Here we create a mapping function and manipulate the y labels to match. Note there is no joint in the line, which may or may not be what you want.

    #!/usr/bin/env gnuplot
    
    reset
    
    set terminal pdfcairo enhanced color lw 3 size 3,2 font 'Arial,14'
    set output 'output2.pdf'
    
    set style data linespoints
    
    set key top left
    
    set title 'my plot'
    set xlabel 'x label'
    set ylabel 'y label'
    
    # mapping function
    map(x) = x <= 1.0 ? x : (x-1.0)/4.0 + 1.0
    
    # upper y bound is set by (5-1.0)/4.0 + 1.0
    set yrange [0:2]
    # y labels create illusion
    set ytics out scale 0.5 nomirror \
      ("0" 0, "1" 1, "2" 1.25, "3" 1.5, "4" 1.75, "5" 2)
    set xtics out scale 0.5 nomirror
    
    plot 'data.dat' u 1:(map($2)) pt 7 title 'my data'
    
    reset
    

    Result:

    enter image description here

    0 讨论(0)
  • 2020-12-18 05:01

    This can be done with set link, which is available only in the 4.7 development version.

    The following script does the mapping, but the labels are on the y2-axis:

    reset
    f(x) = x <= 1 ? x : 1 + (x-1)*4
    i(x) = x <= 1 ? x : (x-1)/4.0 + 1
    set link y2 via f(y) inverse i(y)
    
    unset ytics
    set y2tics mirror
    
    set xrange[0:5]
    set yrange[0:2]
    plot x axes x1y2
    

    Result with 4.7:

    enter image description here

    With some offset, you can move the labels from the y2-axis to the y-axis:

    reset
    set terminal pngcairo size 800,500
    set output 'output.png'
    
    f(x) = x <= 1 ? x : 1 + (x-1)*4
    i(x) = x <= 1 ? x : (x-1)/4.0 + 1
    set link y2 via f(y) inverse i(y)
    
    unset ytics
    set lmargin at screen 0.1
    set rmargin at screen 0.95
    set y2tics mirror offset graph -1.04 right
    # set y2tics add (0.5)
    set my2tics 2
    set y2tics add ('' 0.25 1, '' 0.75 1)
    set ylabel 'ylabel' offset -4
    
    set xrange[0:5]
    set yrange[0:2]
    plot x axes x1y2
    

    That's quite ugly, but it works. It requires just a little fiddling with the left and right margins and the y2tics offset.

    EDIT: I added minor tics, with a higher frequency between 0 and 1. I think it might be useful to add one label for 0.5 to show that the scale is linear, but with a different gradient (in which case you also might want to set y2tics format '%.1f' to have one decimal digit for all labels). However, this tic would also appear as a major tics, because using labels for minor tics is not supported, yet.

    The result is: enter image description here

    0 讨论(0)
提交回复
热议问题