Linking extra ranges?

I have an issue where I can look at data by operating hours or by datetime. I would like to show both of these on along the x axis. I have tried combining them into one categorical axis but it ends up looking like a catastrophe as there is typically 1-2 years of data shown.

So far my best (but still non working) solution is to add an extra x_range, but then I cannot figure out how to get it to link to the existing x axis. Is there a way to do this or some other solution that would get me in the right direction?

Output with one axis.

Output shifted over when second x_range is added same data plotted but against the second range.

Ideally, the data should overlay.

Sample code below.

from bokeh.models import DatetimeTickFormatter, Range1d, NumeralTickFormatter, LinearAxis

from bokeh.plotting import figure

from bokeh.layouts import row

import pandas as pd

from bokeh.io import output_notebook, show
output_notebook()

data_sample = {‘operating_hours’: {‘0’: 5641.0, ‘1’: 5642.0, ‘2’: 5643.0, ‘3’: 5644.0, ‘4’: 5645.0},

‘sensor_reading’: {‘0’: 0.068132542073726654, ‘1’: 0.078682750463485718, ‘2’: 0.071529373526573181, ‘3’: 0.062236662954092026, ‘4’: 0.079991012811660767},

‘timestamp’: {‘0’: ‘2017-01-31 00:00:00’, ‘1’: ‘2017-01-31 00:59:59.999996672’, ‘2’: ‘2017-01-31 02:00:00.000003328’, ‘3’: ‘2017-01-31 03:00:00’, ‘4’: ‘2017-01-31 03:59:59.999996672’}}

df = pd.DataFrame.from_dict(data_sample)

df.timestamp = pd.to_datetime(df.timestamp,infer_datetime_format=True)

p = figure(width=800, height=400, webgl=True)

p.line(df.timestamp, df.sensor_reading,

line_width=1, alpha=0.8, color=’#005195’)

p.circle(df.timestamp, df.sensor_reading,

color=’#005195’, size=2, alpha=0.8)

p.xaxis.formatter = DatetimeTickFormatter(

hours=["%d %B %Y"],

days=["%d %B %Y"],

months=["%d %B %Y"],

years=["%d %B %Y"])

p.extra_x_ranges = {“Hours”: Range1d(start=df.operating_hours.min(),

end=df.operating_hours.max())}

p.circle(df.operating_hours, df.sensor_reading,

x_range_name=‘Hours’, color=“green”, size=2, alpha=0.8)

p.add_layout(LinearAxis(x_range_name=“Hours”, axis_label=“Hours”,

axis_label_text_align=‘left’), “below”)

show§

``

Thanks for your help.

I am surprised no one has any thoughts on this. Maybe my use case is too isolated.

Does anyone know how the second axis decides to anchor and scale relative to the original axis?

Perhaps I can figure out some kind of workaround.

···

On Tuesday, June 13, 2017 at 1:06:59 PM UTC-5, David G wrote:

I have an issue where I can look at data by operating hours or by datetime. I would like to show both of these on along the x axis. I have tried combining them into one categorical axis but it ends up looking like a catastrophe as there is typically 1-2 years of data shown.

So far my best (but still non working) solution is to add an extra x_range, but then I cannot figure out how to get it to link to the existing x axis. Is there a way to do this or some other solution that would get me in the right direction?

Output with one axis.

Output shifted over when second x_range is added same data plotted but against the second range.

Ideally, the data should overlay.

Sample code below.

from bokeh.models import DatetimeTickFormatter, Range1d, NumeralTickFormatter, LinearAxis

from bokeh.plotting import figure

from bokeh.layouts import row

import pandas as pd

from bokeh.io import output_notebook, show
output_notebook()

data_sample = {‘operating_hours’: {‘0’: 5641.0, ‘1’: 5642.0, ‘2’: 5643.0, ‘3’: 5644.0, ‘4’: 5645.0},

‘sensor_reading’: {‘0’: 0.068132542073726654, ‘1’: 0.078682750463485718, ‘2’: 0.071529373526573181, ‘3’: 0.062236662954092026, ‘4’: 0.079991012811660767},

‘timestamp’: {‘0’: ‘2017-01-31 00:00:00’, ‘1’: ‘2017-01-31 00:59:59.999996672’, ‘2’: ‘2017-01-31 02:00:00.000003328’, ‘3’: ‘2017-01-31 03:00:00’, ‘4’: ‘2017-01-31 03:59:59.999996672’}}

df = pd.DataFrame.from_dict(data_sample)

p = figure(width=800, height=400, webgl=True)

p.line(df.timestamp, df.sensor_reading,

line_width=1, alpha=0.8, color=’#005195’)

p.circle(df.timestamp, df.sensor_reading,

color=’#005195’, size=2, alpha=0.8)

p.xaxis.formatter = DatetimeTickFormatter(

hours=["%d %B %Y"],

days=["%d %B %Y"],

months=["%d %B %Y"],

years=["%d %B %Y"])

p.extra_x_ranges = {“Hours”: Range1d(start=df.operating_hours.min(),

end=df.operating_hours.max())}

p.circle(df.operating_hours, df.sensor_reading,

x_range_name=‘Hours’, color=“green”, size=2, alpha=0.8)

p.add_layout(LinearAxis(x_range_name=“Hours”, axis_label=“Hours”,

axis_label_text_align=‘left’), “below”)

show§

df.timestamp = pd.to_datetime(df.timestamp,infer_datetime_format=True)

``

Thanks for your help.

Hi,

I'm not 100% certain of what you are asking about. I think possibly you want to have the about the possibility f using one plot as a "zoom in" for another plot? i.e. you select a range on the top plot then the bottom plot zooms to that smaller range? If so, there is definitely interest in that, just nothing built-in to the library yet. However, you might look at this example in the User's Guide with is very similar to that:

  http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-range-update

If that's not what you are asking for, perhaps you can explain differently, or in more detail?

Thanks,

Bryan

···

On Jun 19, 2017, at 09:40, David G <[email protected]> wrote:

I am surprised no one has any thoughts on this. Maybe my use case is too isolated.

Does anyone know how the second axis decides to anchor and scale relative to the original axis?

Perhaps I can figure out some kind of workaround.

On Tuesday, June 13, 2017 at 1:06:59 PM UTC-5, David G wrote:
I have an issue where I can look at data by operating hours or by datetime. I would like to show both of these on along the x axis. I have tried combining them into one categorical axis but it ends up looking like a catastrophe as there is typically 1-2 years of data shown.

So far my best (but still non working) solution is to add an extra x_range, but then I cannot figure out how to get it to link to the existing x axis. Is there a way to do this or some other solution that would get me in the right direction?

Output with one axis.

Output shifted over when second x_range is added same data plotted but against the second range.

Ideally, the data should overlay.

Sample code below.

from bokeh.models import DatetimeTickFormatter, Range1d, NumeralTickFormatter, LinearAxis
from bokeh.plotting import figure
from bokeh.layouts import row
import pandas as pd
from bokeh.io import output_notebook, show
output_notebook()

data_sample = {'operating_hours': {'0': 5641.0, '1': 5642.0, '2': 5643.0, '3': 5644.0, '4': 5645.0},
               'sensor_reading': {'0': 0.068132542073726654, '1': 0.078682750463485718, '2': 0.071529373526573181, '3': 0.062236662954092026, '4': 0.079991012811660767},
               'timestamp': {'0': '2017-01-31 00:00:00', '1': '2017-01-31 00:59:59.999996672', '2': '2017-01-31 02:00:00.000003328', '3': '2017-01-31 03:00:00', '4': '2017-01-31 03:59:59.999996672'}}

df = pd.DataFrame.from_dict(data_sample)
df.timestamp = pd.to_datetime(df.timestamp,infer_datetime_format=True)

p = figure(width=800, height=400, webgl=True)

p.line(df.timestamp, df.sensor_reading,
       line_width=1, alpha=0.8, color='#005195')
p.circle(df.timestamp, df.sensor_reading,
         color='#005195', size=2, alpha=0.8)

p.xaxis.formatter = DatetimeTickFormatter(
    hours=["%d %B %Y"],
    days=["%d %B %Y"],
    months=["%d %B %Y"],
    years=["%d %B %Y"])

p.extra_x_ranges = {"Hours": Range1d(start=df.operating_hours.min(),
                                     end=df.operating_hours.max())}
p.circle(df.operating_hours, df.sensor_reading,
         x_range_name='Hours', color="green", size=2, alpha=0.8)

p.add_layout(LinearAxis(x_range_name="Hours", axis_label="Hours",
                        axis_label_text_align='left'), "below")

show(p)

Thanks for your help.

--
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/d923f8a1-9c96-4feb-9fe8-11dd89545c73%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi Bryan, Thanks for the reply.

Let me give it another shot . I am using the same data and plots from the first post. The full standalone code is provided in the first post.

I am trying to get 1 Plot with two x axes plotting the same data(sensor_reading) from a data frame by these two x axes(**timestamp **and operating hours).

**timestamp **and operating hours line up with each other by the index shown in the data_sample. But I cannot get them to align with each other on the plot. Two plots shown for understanding. Since nothing goes wrong until I add the second x range to the same plot.

When I add a second x range to the chart it does not align at all. It shifts the first x axis right and compresses it (see below).

The line in the first plot is the sensor_reading vs timestamp. When I add the second x axis with the same data I would expect it to overlay.

In the second plot when I add the extra_x_range withsensor_reading vs operating_hours. The sensor_reading data is the same. Same points, same indices… I would think the values should align but they do not.

I believe what is happening is completely expected behavior. Since when adding an extra_range is shouldn’t have any concrete links to the existing ranges, but it would be nice to be able to specify a couple points for scale and reference so that it does not compress a previous plot as is happening here.

My ideal option is to be able to show both operating_hours and timestamp. Then be able to turn one off as needed.

I hope this is clearer.

Thanks for your time.

Dave

···

On Wednesday, June 21, 2017 at 9:41:25 AM UTC-5, Bryan Van de ven wrote:

Hi,

I’m not 100% certain of what you are asking about. I think possibly you want to have the about the possibility f using one plot as a “zoom in” for another plot? i.e. you select a range on the top plot then the bottom plot zooms to that smaller range? If so, there is definitely interest in that, just nothing built-in to the library yet. However, you might look at this example in the User’s Guide with is very similar to that:

    [http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-range-update](http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-range-update)

If that’s not what you are asking for, perhaps you can explain differently, or in more detail?

Thanks,

Bryan

On Jun 19, 2017, at 09:40, David G [email protected] wrote:

I am surprised no one has any thoughts on this. Maybe my use case is too isolated.

Does anyone know how the second axis decides to anchor and scale relative to the original axis?

Perhaps I can figure out some kind of workaround.

On Tuesday, June 13, 2017 at 1:06:59 PM UTC-5, David G wrote:

I have an issue where I can look at data by operating hours or by datetime. I would like to show both of these on along the x axis. I have tried combining them into one categorical axis but it ends up looking like a catastrophe as there is typically 1-2 years of data shown.

So far my best (but still non working) solution is to add an extra x_range, but then I cannot figure out how to get it to link to the existing x axis. Is there a way to do this or some other solution that would get me in the right direction?

Output with one axis.

Output shifted over when second x_range is added same data plotted but against the second range.

Ideally, the data should overlay.

Sample code below.

from bokeh.models import DatetimeTickFormatter, Range1d, NumeralTickFormatter, LinearAxis

from bokeh.plotting import figure

from bokeh.layouts import row

import pandas as pd

from bokeh.io import output_notebook, show

output_notebook()

data_sample = {‘operating_hours’: {‘0’: 5641.0, ‘1’: 5642.0, ‘2’: 5643.0, ‘3’: 5644.0, ‘4’: 5645.0},
‘sensor_reading’: {‘0’: 0.068132542073726654, ‘1’: 0.078682750463485718, ‘2’: 0.071529373526573181, ‘3’: 0.062236662954092026, ‘4’: 0.079991012811660767},
‘timestamp’: {‘0’: ‘2017-01-31 00:00:00’, ‘1’: ‘2017-01-31 00:59:59.999996672’, ‘2’: ‘2017-01-31 02:00:00.000003328’, ‘3’: ‘2017-01-31 03:00:00’, ‘4’: ‘2017-01-31 03:59:59.999996672’}}

df = pd.DataFrame.from_dict(data_sample)

df.timestamp = pd.to_datetime(df.timestamp,infer_datetime_format=True)

p = figure(width=800, height=400, webgl=True)

p.line(df.timestamp, df.sensor_reading,

   line_width=1, alpha=0.8, color='#005195')

p.circle(df.timestamp, df.sensor_reading,

     color='#005195', size=2, alpha=0.8)

p.xaxis.formatter = DatetimeTickFormatter(

hours=["%d %B %Y"],
days=["%d %B %Y"],
months=["%d %B %Y"],
years=["%d %B %Y"])

p.extra_x_ranges = {“Hours”: Range1d(start=df.operating_hours.min(),

                                 end=df.operating_hours.max())}

p.circle(df.operating_hours, df.sensor_reading,

     x_range_name='Hours', color="green", size=2, alpha=0.8)

p.add_layout(LinearAxis(x_range_name=“Hours”, axis_label=“Hours”,

                    axis_label_text_align='left'), "below")

show§

Thanks for your help.


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/d923f8a1-9c96-4feb-9fe8-11dd89545c73%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi,

Unfortunately I don't think this is going to be successful currently. As you have discovered, extra axes and range have to be "synced up" to the defaults so that they pan/zoom correctly together, and this only happens and plot initialization time. That pretty much precludes adding new ranges and axes after the fact. A better option might be to add an axis from the start then show/hide it as needed, but I suspect there would be issues with this as well. I can only suggest opening a GH feature request for this at the moment.

Thanks,

Bryan

···

On Jun 21, 2017, at 10:41, David G <[email protected]> wrote:

Hi Bryan, Thanks for the reply.

Let me give it another shot . I am using the same data and plots from the first post. The full standalone code is provided in the first post.

I am trying to get 1 Plot with two x axes plotting the same data(sensor_reading) from a data frame by these two x axes(timestamp and operating hours).

timestamp and operating hours line up with each other by the index shown in the data_sample. But I cannot get them to align with each other on the plot. Two plots shown for understanding. Since nothing goes wrong until I add the second x range to the same plot.

When I add a second x range to the chart it does not align at all. It shifts the first x axis right and compresses it (see below).

The line in the first plot is the sensor_reading vs timestamp. When I add the second x axis with the same data I would expect it to overlay.
In the second plot when I add the extra_x_range with sensor_reading vs operating_hours. The sensor_reading data is the same. Same points, same indices.... I would think the values should align but they do not.

I believe what is happening is completely expected behavior. Since when adding an extra_range is shouldn't have any concrete links to the existing ranges, but it would be nice to be able to specify a couple points for scale and reference so that it does not compress a previous plot as is happening here.

My ideal option is to be able to show both operating_hours and timestamp. Then be able to turn one off as needed.

I hope this is clearer.

Thanks for your time.
Dave

On Wednesday, June 21, 2017 at 9:41:25 AM UTC-5, Bryan Van de ven wrote:
Hi,

I'm not 100% certain of what you are asking about. I think possibly you want to have the about the possibility f using one plot as a "zoom in" for another plot? i.e. you select a range on the top plot then the bottom plot zooms to that smaller range? If so, there is definitely interest in that, just nothing built-in to the library yet. However, you might look at this example in the User's Guide with is very similar to that:

        http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-range-update

If that's not what you are asking for, perhaps you can explain differently, or in more detail?

Thanks,

Bryan

> On Jun 19, 2017, at 09:40, David G <[email protected]> wrote:
>
> I am surprised no one has any thoughts on this. Maybe my use case is too isolated.
>
> Does anyone know how the second axis decides to anchor and scale relative to the original axis?
>
> Perhaps I can figure out some kind of workaround.
>
>
>
> On Tuesday, June 13, 2017 at 1:06:59 PM UTC-5, David G wrote:
> I have an issue where I can look at data by operating hours or by datetime. I would like to show both of these on along the x axis. I have tried combining them into one categorical axis but it ends up looking like a catastrophe as there is typically 1-2 years of data shown.
>
> So far my best (but still non working) solution is to add an extra x_range, but then I cannot figure out how to get it to link to the existing x axis. Is there a way to do this or some other solution that would get me in the right direction?
>
>
> Output with one axis.
>
>
> Output shifted over when second x_range is added same data plotted but against the second range.
>
>
> Ideally, the data should overlay.
>
>
> Sample code below.
>
>
> from bokeh.models import DatetimeTickFormatter, Range1d, NumeralTickFormatter, LinearAxis
> from bokeh.plotting import figure
> from bokeh.layouts import row
> import pandas as pd
> from bokeh.io import output_notebook, show
> output_notebook()
>
> data_sample = {'operating_hours': {'0': 5641.0, '1': 5642.0, '2': 5643.0, '3': 5644.0, '4': 5645.0},
> 'sensor_reading': {'0': 0.068132542073726654, '1': 0.078682750463485718, '2': 0.071529373526573181, '3': 0.062236662954092026, '4': 0.079991012811660767},
> 'timestamp': {'0': '2017-01-31 00:00:00', '1': '2017-01-31 00:59:59.999996672', '2': '2017-01-31 02:00:00.000003328', '3': '2017-01-31 03:00:00', '4': '2017-01-31 03:59:59.999996672'}}
>
> df = pd.DataFrame.from_dict(data_sample)
> df.timestamp = pd.to_datetime(df.timestamp,infer_datetime_format=True)
>
> p = figure(width=800, height=400, webgl=True)
>
>
> p.line(df.timestamp, df.sensor_reading,
> line_width=1, alpha=0.8, color='#005195')
> p.circle(df.timestamp, df.sensor_reading,
> color='#005195', size=2, alpha=0.8)
>
> p.xaxis.formatter = DatetimeTickFormatter(
> hours=["%d %B %Y"],
> days=["%d %B %Y"],
> months=["%d %B %Y"],
> years=["%d %B %Y"])
>
> p.extra_x_ranges = {"Hours": Range1d(start=df.operating_hours.min(),
> end=df.operating_hours.max())}
> p.circle(df.operating_hours, df.sensor_reading,
> x_range_name='Hours', color="green", size=2, alpha=0.8)
>
> p.add_layout(LinearAxis(x_range_name="Hours", axis_label="Hours",
> axis_label_text_align='left'), "below")
>
> show(p)
>
>
> Thanks for your help.
>
>
>
> --
> 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/d923f8a1-9c96-4feb-9fe8-11dd89545c73%40continuum.io.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout.

--
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/db2aea04-0e86-4446-bf36-2db275db2a30%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.