Auto set vbar line_width based on x_range in Bokeh
bokeh, graph, python
Solution
I finally figured this out with help from @bigreddot. It turns out that I was using the wrong property. Instead of using `line_width` I needed to use `width`. Since my `x_range` is a `datetime` range, and `datetimes` are expressed in milliseconds, I needed a large enough width to display correctly. This takes care of setting a proportional width when zooming in, since the width represents a specific period on the `x_axis`.
Since I have a function to change the `freq` of how I group my columns and update my `ColumnDataSource.data`, I just need to re-calculate the `width` when I update it.
Here's the working code:
def get_data(freq='MS'):
return pd.DataFrame(srs.groupby(pd.Grouper(freq=freq)).mean())
source = ColumnDataSource(data=ColumnDataSource.from_df(get_data()))
def get_width():
mindate = min(source.data['date'])
maxdate = max(source.data['date'])
return 0.8 * (maxdate-mindate).total_seconds()*1000 / len(source.data['date'])
f = figure(plot_width=550, plot_height=400, x_axis_type="datetime")
f.x_range.set(bounds='auto')
r = f.vbar(source=source, top='volume', x='date', width=get_width())
bar_glyph = f.renderers[-1].glyph
handle = show(f, notebook_handle=True)
and my update function:
def update_data(freq={'Quarter': 'QS', 'Month': 'MS', 'Week': 'W'}):
source.data = ColumnDataSource.from_df(get_data(freq))
r.glyph.width = get_width()
push_notebook()
i = interact(update_data)
Problem
I have a `vbar` tied to a `ColumnDataSource` which gets updated based on some widget selections. If I start with `line_width=5` it looks great with my initial data. However, when I update the graph, the `x_range` gets updated to fit the updated data and causes the relative width of the bars to change. Ideally, the width should always be proportional to the number of bars displayed. I tried looking at the various properties on the `x_range` and `xaxis` to see if I could get the range and try to calculate the width myself but I haven't found anything that helps. Been looking around and the documentation and nothing. Any thoughts?