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 half [1:5] and i do not want to use logarithmic scale.
The best thing would be the possibility to provide a mapping function. Sure one could directly map the function results but then the labes will not fit to the actual data.
Is there any possiblilty? I searched a bit but iam not sure if i missed something or if it is not possible.
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:
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:
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
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:
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With