Incorrect alignment between two vertical axes

Hi,

I’m trying to add a second vertical axes to a simple lineplot showing temperature values in Celcius and Fahrenheit. But if you zoom into the areas marked with red circles you’ll see that the second (right) axis’ range is mapped to the entire plot height instead of only the range between minimum and maximum tick (or data) values of the original (left) axis. Please see attached sample code. Is there an easy fix to solve that?

Thanks!

test_bokeh_two_vertical_axes.py (1.54 KB)

The problem stems from the fact that the default ranges are "DataRanges" they try to automatically determine the envelope of all data, plus add a little padding, so that everything shows up comfortably in the plot automatically. So if you look carefully, you will notice the initial celsius bounds are not (0,100) they are slightly bigger than that. But you do set the Fahrenheit bounds explicitly to what should be (0,100):

  p.extra_y_ranges = {"fahrenheit": Range1d(start=min(y) * 9/5. + 32, end=max(y) * 9/5. + 32)}

So to fix this, you can set the celsius range explicitly so that the initial ranges line up correctly (and the initial ranges are what determines the relative scaling when zooming, e.g). You can do this either by passing

  y_range=(0,100)

to the figure function call, or by setting the y_range attribute after the fact:

  p.y_range=Range1d(0,100)

Thanks,

Bryan

···

On Aug 24, 2015, at 8:09 AM, [email protected] wrote:

Hi,

I'm trying to add a second vertical axes to a simple lineplot showing temperature values in Celcius and Fahrenheit. But if you zoom into the areas marked with red circles you'll see that the second (right) axis' range is mapped to the entire plot height instead of only the range between minimum and maximum tick (or data) values of the original (left) axis. Please see attached sample code. Is there an easy fix to solve that?

Thanks!

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/635f1684-baef-4671-84b9-daf9bb49e5fc%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.
<test_bokeh_two_vertical_axes.py>

That works nicely, thanks!

Let’s say I want to keep some padding, though, for better optical results. This DataRange1D class in http://bokeh.pydata.org/en/dev/docs/reference/models/ranges.html should come in handy. In fact, I can add this to the left axis easily like this (overwriting the default value, I suppose):

ydr = DataRange1d(range_padding=0.05)
p = figure(title=“Double vertical axis example”,
x_axis_label=‘Time (h)’, y_axis_label=‘Temp. (°C)’,
y_range=ydr)

But it’s not clear where to add the same for the second (right) axis. I’ve tried in LinearAxis, but no luck. Is that possible, too?

Thanks!

Bryan Van de ven:

···

So to fix this, you can set the celsius range explicitly so that the initial ranges line up correctly (and the initial ranges are what determines the relative scaling when zooming, e.g). You can do this either by passing

    y_range=(0,100)

to the figure function call, or by setting the y_range attribute after the fact:

    p.y_range=Range1d(0,100)

I would say it is currently problematic to get twin axes working correctly with DataRanges. The reason is because the computed range is not known on the python side, it is computed in the browser. So there is no ahead of time to know what to set the second range limits too. It's possible there could be some nice way to express a scaling linkage explicitly, but this would be new development. For now I think you will have to set all the ranges explicitly.

Bryan

···

On Aug 24, 2015, at 10:00 AM, [email protected] wrote:

That works nicely, thanks!

Let's say I want to keep some padding, though, for better optical results. This DataRange1D class in http://bokeh.pydata.org/en/dev/docs/reference/models/ranges.html should come in handy. In fact, I can add this to the left axis easily like this (overwriting the default value, I suppose):

ydr = DataRange1d(range_padding=0.05)
p = figure(title="Double vertical axis example",
    x_axis_label='Time (h)', y_axis_label='Temp. (°C)',
    y_range=ydr)

But it's not clear where to add the same for the second (right) axis. I've tried in LinearAxis, but no luck. Is that possible, too?

Thanks!

Bryan Van de ven:
So to fix this, you can set the celsius range explicitly so that the initial ranges line up correctly (and the initial ranges are what determines the relative scaling when zooming, e.g). You can do this either by passing

        y_range=(0,100)

to the figure function call, or by setting the y_range attribute after the fact:

        p.y_range=Range1d(0,100)

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/5cad8ac1-ba75-45d9-826e-4e4ca6444d9a%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Fair enough, as this is entirely, and easily, doable (at least when you know your data range in advance). See attached edited version.

Thanks again!

Bryan Van de ven:

test_bokeh_two_vertical_axes.py (1.81 KB)

···

I would say it is currently problematic to get twin axes working correctly with DataRanges. The reason is because the computed range is not known on the python side, it is computed in the browser. So there is no ahead of time to know what to set the second range limits too. It’s possible there could be some nice way to express a scaling linkage explicitly, but this would be new development. For now I think you will have to set all the ranges explicitly.

Bryan