簡體   English   中英

python bokeh:在回調上更新散點圖顏色

[英]python bokeh: update scatter plot colors on callback

我最近才開始使用Bokeh。 我有一個散點圖,在該圖中,我想根據某個第三屬性(例如數量,而x軸是日期,y軸是該時間點的給定值)為每個標記着色。

假設我的數據在一個數據框中,我設法使用線性顏色圖做到了這一點,如下所示:

min_q = df.quantity.min()
max_q = df.quantity.max()
mapper = linear_cmap(field_name='quantity', palette=palettes.Spectral6, low=min_q, high=max_q)
source = ColumnDataSource(data=get_data(df))

p = figure(x_axis_type="datetime")
p.scatter(x="date_column", y="value", marker="triangle", fill_color=mapper, line_color=None, source=source)
color_bar = ColorBar(color_mapper=mapper['transform'], width=8,  location=(0,0))
p.add_layout(color_bar, 'right')

這似乎按預期工作。 下面是啟動bokeh服務器時得到的圖。

在此處輸入圖片說明

然后,我有一個在某些小部件(選擇或時間選擇器)中更改值時觸發的回調函數update( )。

def update():
    # get new df (according to new date/select)
    df = get_df()
    # update min/max for colormap
    min_q = df.quantity.min()
    max_q = df.quantity.max()
    # I think I should not create a new mapper but doing so I get closer
    mapper = linear_cmap(field_name='quantity', palette=palettes.Spectral6 ,low=min_q, high=max_q)
    color_bar.color_mapper=mapper['transform'] 
    source.data = get_data(df)
    # etc

這是我能得到的最接近的。 顏色圖將使用新值進行更新,但是標記的顏色似乎仍然遵循原始圖案。 參見下圖(鑒於該數量,我期望為綠色,但它是藍色的,因為在回調之前的第一個圖的地圖中它仍被視為<4000)。

在此處輸入圖片說明

我是否應該在數據框中添加“顏色”列? 我覺得有一種更容易/更方便的方法。

編輯 :這是一個使用bigreddot答案的最小工作示例:

from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.plotting import figure
from bokeh.models import Button, ColumnDataSource, ColorBar, HoverTool
from bokeh.palettes import Spectral6
from bokeh.transform import linear_cmap
import numpy as np

x = [1,2,3,4,5,7,8,9,10]
y = [1,2,3,4,5,7,8,9,10]
z = [1,2,3,4,5,7,8,9,10]



source = ColumnDataSource(dict(x=x, y=y, z=z))

#Use the field name of the column source
mapper = linear_cmap(field_name='z', palette=Spectral6 ,low=min(y) ,high=max(y))

p = figure(plot_width=300, plot_height=300, title="Linear Color Map Based on Y")
p.circle(x='x', y='y', line_color=mapper,color=mapper, fill_alpha=1, size=12, source=source)

color_bar = ColorBar(color_mapper=mapper['transform'], width=8,  location=(0,0))
p.add_tools(HoverTool(tooltips="@z", show_arrow=False, point_policy='follow_mouse'))
p.add_layout(color_bar, 'right')

b = Button()

def update():
    new_z = np.exp2(z)
    mapper = linear_cmap(field_name='z', palette=Spectral6 ,low=min(new_z), high=max(new_z))
    color_bar.color_mapper=mapper['transform'] 
    source.data = dict(x=x, y=y, z=new_z)

b.on_click(update)

curdoc().add_root(column(b, p))

更新后,圓圈將按照原始比例進行着色:大於10的所有內容均為紅色。 取而代之的是,我希望所有的東西都是藍色的,直到頂部的最后3個圓圈分別應被分別塗成綠色黃色和紅色。

可能是一個錯誤,請隨時打開GitHub問題。

也就是說,以上代碼並不代表使用Bokeh的最佳做法,即: 始終進行盡可能小的更新 在這種情況下,這意味着在現有顏色轉換上設置新的屬性值,而不是替換現有顏色轉換。

這是一個完整的工作示例(由Bokeh 1.0.2制作),演示了字形的色圖顏色響應於數據列的更改而更新:

from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.plotting import figure
from bokeh.models import Button, ColumnDataSource, ColorBar
from bokeh.palettes import Spectral6
from bokeh.transform import linear_cmap

x = [1,2,3,4,5,7,8,9,10]
y = [1,2,3,4,5,7,8,9,10]
z = [1,2,3,4,5,7,8,9,10]

#Use the field name of the column source
mapper = linear_cmap(field_name='z', palette=Spectral6 ,low=min(y) ,high=max(y))

source = ColumnDataSource(dict(x=x, y=y, z=z))

p = figure(plot_width=300, plot_height=300, title="Linear Color Map Based on Y")
p.circle(x='x', y='y', line_color=mapper,color=mapper, fill_alpha=1, size=12, source=source)

color_bar = ColorBar(color_mapper=mapper['transform'], width=8,  location=(0,0))
p.add_layout(color_bar, 'right')

b = Button()

def update():
    new_z = np.exp2(z)

    # update the existing transform
    mapper['transform'].low=min(new_z)
    mapper['transform'].high=max(new_z)

    source.data = dict(x=x, y=y, z=new_z)

b.on_click(update)

curdoc().add_root(column(b, p))

這是原始圖:

在此處輸入圖片說明

這是單擊按鈕后的更新圖

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM