I am trying to calculate a (cross-sectional) average for each major interval on an x-axis, in order to do this I have to retrieve the label interval. My X-axis p.axis.ticker
ticker is a BasicTicker
object. This object has a base=10
and mantissas=[1, 2, 5]
.
I see on the x-axis that the labels show with an interval of 20 units (this number is what I am after), but another complication is that the figure is dynamic. The variable used for the X-axis can be changed, and therefore the interval automatically changes due to scaling (some variables are in the range of 0.1-0.5, others 5-10 e.g.). For this reason I need to gain access to the interval variable.
from bokeh.io import curdoc
from bokeh.layouts import column, layout
from bokeh.models import ColumnDataSource, Select
from bokeh.plotting import figure
axis_map = {
"Return": "ret",
"Holding period": "holdp",
"Data source": "source",
}
x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Holding period")
y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Return")
source = ColumnDataSource(data=dict(x=[], y=[]))
p = figure(plot_height=600, plot_width=700, title="", sizing_mode="scale_both")
scatter = p.scatter(x="x", y="y", source=source, size=4, color="color", fill_alpha="alpha", marker="marker")
def update_data()
...
interval = p.axis.ticker.*get_interval()*
df['interval_group'] = df[x_name].apply(lambda x: interval*round(x/interval))
y_avg = df.groupby('interval_group')[y_name].mean()
source.data = dict(x=..,
y=..,
y_avg=y_avg
)
controls = [x_axis, y_axis]
for control in controls:
control.on_change('value', lambda attr, old, new: update())
inputs = column(*controls, width=320, height=1000)
inputs.sizing_mode = "fixed"
l = layout([
[inputs, p, h],
], sizing_mode="scale_both")
update()
doc = curdoc()
doc.add_root(l)
doc.title = "Test"
In BokehJS, ContinuousTicker
(a parent class of BasicTicker
) has an abstract get_interval
method - seems like it's exactly what you need. But neither this method nor anything that uses it is exposed on the Python side. Well, at least as far as I can tell.
To get the required value, I would either recreate the body of the get_interval
method in Python or create a custom ticker (or an axis, likely) where the only custom behavior is to send the computed value to the Python side.