2
votes

Is it possible to plot a graph using different scale for negative and positive values in y-axes in Gnuplot?

I want to set the y range of the values in the y-axes from -2 to 70. For values from 0 to 70 I want a scale e.g. 0,10,20,30,..70. For values from 0 to -2 I want a different scale: 0, -0.1, -0.2, -0.3,..-2.

Thanks in advance.

3
Did you have a look at multiplot? Maybe you give us some data to play with. - vaettchen
Use set nonlinear with the adequate mapping functions. - Christoph
@vaettchen, here is my .dat file pastebin.com/dU1Hpw8T I will check that. Thanks! - v1mm3r
@Christoph, sounds promising. You mean for f(x) in [-2:0] and f(x) in [0:70] apply different set nonlinear? Can you give a short example please. Meanwhile I am checking for that. - v1mm3r
Unfortunately, I didn't find anything helpful to plot my graphs. I am working with a clustered histogram. I tried set link and also set nonlinear but didn't achieve desired results. Maybe that I have also negative values in the y-axes. Could you please give any suggestion? I want to have a different scale and step size for values from -2 to 0 because my values varies a lot (one value is 68 and one another -0.04) Thanks - v1mm3r

3 Answers

2
votes

Understanding your intention in general, I'm not sure whether the data you are providing are good enough to illustrate your desired outcome, so I have added two more data points where the negative y axis section is actually being used (see at the bottom of the post).

I used

  • multiplot to produce two separate plots, one for y values larger and one for those smaller than zero
  • the ternary operator (a ? b : c) to separate the date for each plot

I have done no work on the resulting graph, so it is extremely basic, and the large point size and different shape is only to "make the point". This is not a solution but should get you started:

# set up multiplot so that the two subgraphs are joined
set multiplot layout 2,1 margins 0.1,0.95,0.1,0.95 spacing 0
# no titles please
unset key
# we don't want tics for the upper half
unset xtics

plot[-2:2][0:70] "so.dat" using 2:($3>0?$3:NaN)\
                 w points pt 7 ps 2

# we do want xtics at the bottom
set xtics
plot[-2:2][-2:0] "so.dat" using 2:($3<0?$3:NaN)\
                 w points pt 5 ps 2

# cleanup
unset multiplot
reset

yields

enter image description here

My version of the data so.dat:

#                   TCP                     TFO
"Preparation"       1.126717                68.852979 
"Establishment"     -0.0436158              1.5529298
"Transfer"          -0.1172298              0.5735358
"Interruption"      0.125                   -1.25
"Execution"         -1.5                    -0.05
2
votes

This has an answer already that has been accepted, but I have done some more work that I want to share; in particular,I wanted to have more control over the two subgraphs than the line

set multiplot layout 2,1 margins 0.1,0.95,0.1,0.95 spacing 0

allows. The lower subgraph should be visibly "thinner" than the upper one. Taking the opportunity, I also wanted to address Vladimir's question in his comment. So here we go:

### set up multiplot so that the two subgraphs are joined
set multiplot
 # we need to set a left margin to keep the subgraphs aligned,
 # and we need enough space for the ylabel
set lmargin 10
# no bottom margin, so that the second subgraph touches the upper one
set bmargin 0
# no titles please
unset key
# but we want a ylabel
set ylabel "Scales"
# no xtics
unset xtics

For Vladimir: see help set border

# we want left, top and right 2 + 4 + 8
# but no bottom border
set border 14

Now manually fix the area where we want to draw the first subgraph:

set size 1,0.5                          # full with, half hight
set origin 0,0.5                        # start at the left border, half way up
# optional: colour background
# set object 1 rect from -2,0 to 2,80 fc rgb "yellow" fillstyle solid .15 noborder

Ready to draw the graph:

plot[-2:2][0:80] "so.dat" using 2:($3>0?$3:NaN)\
                  w points pt 7 ps 2

The rest in one go:

# we do want xtics a label at the bottom
set xtics -2,.5,2 nomirror
set xlabel "Multiplot In Action"
set ylabel "Different"

set size 1,0.3                  # full width, 30% of height, keep space for xlabel
set origin 0,0.2                # left, keep bottom 20% free
set tmargin 0                   # no top margin, touch the upper subgraph
set bmargin 2                   # for the xlabel
set border 11                   # we want left, bottom and right border, no top 1 + 2 + 8
# set object 2 rect from -2,-2 to 2,0 fc rgb "blue" fillstyle solid .15 noborder
plot[-2:2][-2:0] "so.dat" using 2:($3<0?$3:NaN)\
                 w points pt 5 ps 2

# cleanup
unset multiplot
reset

This gives us

enter image description here

I would have liked the colour backgrounds, but the lower one is drawing over the dots in the upper one and I have not been able to fix that (back doesn't help).

1
votes

Since gnuplot 5.2 you can define nonlinear coordinate systems with set nonlinear. This works similar to set link: You must provide a mapping function and its inverse for the axis you want to change.

In your case, the mapping function would scale all positive y-values and leave the negative ones unscaled:

RATIO=0.1
map(y) = y > 0 ? y*RATIO : y
inv_map(y) = y > 0 ? y/RATIO : y
set nonlinear y via map(y) inverse inv_map(y)

set xrange[-5:50]
plot x 

enter image description here