2016-10-21 2 views
1

У меня есть vbar привязан к ColumnDataSource, который обновляется на основе некоторых вариантов выбора виджета. Если я начинаю с line_width=5, он отлично выглядит с моими исходными данными. Однако, когда я обновляю график, x_range обновляется, чтобы соответствовать обновленным данным и вызывает изменение относительной ширины баров.Автоматический набор vbar line_width на основе x_range в Bokeh

В идеале ширина всегда должна быть пропорциональна количеству отображаемых полосок. Я попытался взглянуть на различные свойства на x_range и xaxis, чтобы узнать, могу ли я получить диапазон и попытаться рассчитать ширину самостоятельно, но я не нашел ничего, что поможет. Оглядываясь, документация и ничего. Есть предположения?

ответ

3

Я, наконец, понял это с помощью @bigreddot. Оказывается, я использовал неправильное свойство. Вместо использования line_width мне нужно было использовать width. Так как мой x_range - это диапазон datetime, а datetimes выражены в миллисекундах, мне нужно было достаточно большой ширины для правильной отображения. Это обеспечивает настройку пропорциональной ширины при масштабировании, так как ширина представляет определенный период на x_axis.

Поскольку у меня есть функция для изменения freq того, как я группирую свои столбцы и обновляю свой ColumnDataSource.data, мне просто нужно пересчитать width, когда я его обновляю.

Вот рабочий код:

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) 

и моя функция обновления:

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) 
Смежные вопросы