带滑块过滤器的直方图
Histogram with slider filter
我想创建一个直方图,其中密度图在散景中与滑块过滤器相结合。 Atm,我有一些块可以创建散景直方图,其中包含来自另一个线程的密度图。我不知道如何创建回调函数来更新数据并重新渲染绘图。
from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.sampledata.autompg import autompg as df
from numpy import histogram, linspace
from scipy.stats.kde import gaussian_kde
pdf = gaussian_kde(df.hp)
x = linspace(0,250,50)
p = figure(plot_height=300)
p.line(x, pdf(x))
# plot actual hist for comparison
hist, edges = histogram(df.hp, density=True, bins=20)
p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:], alpha=0.4)
show(p)
在 Bokeh 中实现回调有两种方式:
- 和 JS code。在那种情况下,该图仍然是一个独立的对象,约束是您需要在 Javascript 内进行任何数据操作(该声明有一个小警告但此处不相关:
scipy
不能从这样的回调中调用)
- 通过在 Bokeh server 中执行回调,在这种情况下,您可以使用 python 的全部武器库。代价是,与第一种情况相比,绘制和分发图表要多一些(但这并不困难,请参见示例)。
考虑到每次更改过滤条件都需要重新安装kde,第二种方式是唯一的选择(除非你想在javascript...中这样做)。
这就是您要执行的操作(在 cyl
上使用过滤器的示例):
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.io import output_notebook, show
from bokeh.layouts import column
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, Select
from bokeh.sampledata.autompg import autompg as df
from numpy import histogram, linspace
from scipy.stats.kde import gaussian_kde
output_notebook()
def modify_doc(doc):
x = linspace(0,250,50)
source_hist = ColumnDataSource({'top': [], 'left': [], 'right': []})
source_kde = ColumnDataSource({'x': [], 'y': []})
p = figure(plot_height=300)
p.line(x='x', y='y', source=source_kde)
p.quad(top='top', bottom=0, left='left', right='right', alpha=0.4, source=source_hist)
def update(attr, old, new):
if new == 'All':
filtered_df = df
else:
condition = df.cyl == int(new)
filtered_df = df[condition]
hist, edges = histogram(filtered_df.hp, density=True, bins=20)
pdf = gaussian_kde(filtered_df.hp)
source_hist.data = {'top': hist, 'left': edges[:-1], 'right': edges[1:]}
source_kde.data = {'x': x, 'y': pdf(x)}
update(None, None, 'All')
select = Select(title='# cyl', value='All', options=['All'] + [str(i) for i in df.cyl.unique()])
select.on_change('value', update)
doc.add_root(column(select, p))
# To run it in the notebook:
plot = Application(FunctionHandler(modify_doc))
show(plot)
# Or to run it stand-alone with `bokeh serve --show myapp.py`
# in which case you need to remove the `output_notebook()` call
# from bokeh.io import curdoc
# modify_doc(curdoc())
一些注意事项:
- 这在 jupyter notebook 中被设为 运行(参见
output_notebook()
和最后未注释的两行)。
- 到 运行 它外面,注释笔记本行(见上文)并取消注释最后两行。然后你可以从命令行运行它。
Select
只会处理 str
值,因此您需要在(创建它时)和输出(在使用值时:old
和 new
)进行转换
- 对于多个过滤器,您需要同时访问每个
Select
的状态。您可以通过在定义 update
函数之前实例化 Select
来做到这一点(但还没有任何回调!)并保留对它们的引用,使用 your_ref.value
访问它们的值并构建您的条件接着就,随即。在 update
定义之后,您可以在每个 Select
. 上附加回调
最后,一个多选的例子:
def modify_doc(doc):
x = linspace(0,250,50)
source_hist = ColumnDataSource({'top': [], 'left': [], 'right': []})
source_kde = ColumnDataSource({'x': [], 'y': []})
p = figure(plot_height=300)
p.line(x='x', y='y', source=source_kde)
p.quad(top='top', bottom=0, left='left', right='right', alpha=0.4, source=source_hist)
select_cyl = Select(title='# cyl', value='All', options=['All'] + [str(i) for i in df.cyl.unique()])
select_ori = Select(title='origin', value='All', options=['All'] + [str(i) for i in df.origin.unique()])
def update(attr, old, new):
all = pd.Series(True, index=df.index)
if select_cyl.value == 'All':
cond_cyl = all
else:
cond_cyl = df.cyl == int(select_cyl.value)
if select_ori.value == 'All':
cond_ori = all
else:
cond_ori = df.origin == int(select_ori.value)
filtered_df = df[cond_cyl & cond_ori]
hist, edges = histogram(filtered_df.hp, density=True, bins=20)
pdf = gaussian_kde(filtered_df.hp)
source_hist.data = {'top': hist, 'left': edges[:-1], 'right': edges[1:]}
source_kde.data = {'x': x, 'y': pdf(x)}
update(None, None, 'All')
select_ori.on_change('value', update)
select_cyl.on_change('value', update)
doc.add_root(column(select_ori, select_cyl, p))
我想创建一个直方图,其中密度图在散景中与滑块过滤器相结合。 Atm,我有一些块可以创建散景直方图,其中包含来自另一个线程的密度图。我不知道如何创建回调函数来更新数据并重新渲染绘图。
from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.sampledata.autompg import autompg as df
from numpy import histogram, linspace
from scipy.stats.kde import gaussian_kde
pdf = gaussian_kde(df.hp)
x = linspace(0,250,50)
p = figure(plot_height=300)
p.line(x, pdf(x))
# plot actual hist for comparison
hist, edges = histogram(df.hp, density=True, bins=20)
p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:], alpha=0.4)
show(p)
在 Bokeh 中实现回调有两种方式:
- 和 JS code。在那种情况下,该图仍然是一个独立的对象,约束是您需要在 Javascript 内进行任何数据操作(该声明有一个小警告但此处不相关:
scipy
不能从这样的回调中调用) - 通过在 Bokeh server 中执行回调,在这种情况下,您可以使用 python 的全部武器库。代价是,与第一种情况相比,绘制和分发图表要多一些(但这并不困难,请参见示例)。
考虑到每次更改过滤条件都需要重新安装kde,第二种方式是唯一的选择(除非你想在javascript...中这样做)。
这就是您要执行的操作(在 cyl
上使用过滤器的示例):
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.io import output_notebook, show
from bokeh.layouts import column
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, Select
from bokeh.sampledata.autompg import autompg as df
from numpy import histogram, linspace
from scipy.stats.kde import gaussian_kde
output_notebook()
def modify_doc(doc):
x = linspace(0,250,50)
source_hist = ColumnDataSource({'top': [], 'left': [], 'right': []})
source_kde = ColumnDataSource({'x': [], 'y': []})
p = figure(plot_height=300)
p.line(x='x', y='y', source=source_kde)
p.quad(top='top', bottom=0, left='left', right='right', alpha=0.4, source=source_hist)
def update(attr, old, new):
if new == 'All':
filtered_df = df
else:
condition = df.cyl == int(new)
filtered_df = df[condition]
hist, edges = histogram(filtered_df.hp, density=True, bins=20)
pdf = gaussian_kde(filtered_df.hp)
source_hist.data = {'top': hist, 'left': edges[:-1], 'right': edges[1:]}
source_kde.data = {'x': x, 'y': pdf(x)}
update(None, None, 'All')
select = Select(title='# cyl', value='All', options=['All'] + [str(i) for i in df.cyl.unique()])
select.on_change('value', update)
doc.add_root(column(select, p))
# To run it in the notebook:
plot = Application(FunctionHandler(modify_doc))
show(plot)
# Or to run it stand-alone with `bokeh serve --show myapp.py`
# in which case you need to remove the `output_notebook()` call
# from bokeh.io import curdoc
# modify_doc(curdoc())
一些注意事项:
- 这在 jupyter notebook 中被设为 运行(参见
output_notebook()
和最后未注释的两行)。 - 到 运行 它外面,注释笔记本行(见上文)并取消注释最后两行。然后你可以从命令行运行它。
Select
只会处理str
值,因此您需要在(创建它时)和输出(在使用值时:old
和new
)进行转换- 对于多个过滤器,您需要同时访问每个
Select
的状态。您可以通过在定义update
函数之前实例化Select
来做到这一点(但还没有任何回调!)并保留对它们的引用,使用your_ref.value
访问它们的值并构建您的条件接着就,随即。在update
定义之后,您可以在每个Select
. 上附加回调
最后,一个多选的例子:
def modify_doc(doc):
x = linspace(0,250,50)
source_hist = ColumnDataSource({'top': [], 'left': [], 'right': []})
source_kde = ColumnDataSource({'x': [], 'y': []})
p = figure(plot_height=300)
p.line(x='x', y='y', source=source_kde)
p.quad(top='top', bottom=0, left='left', right='right', alpha=0.4, source=source_hist)
select_cyl = Select(title='# cyl', value='All', options=['All'] + [str(i) for i in df.cyl.unique()])
select_ori = Select(title='origin', value='All', options=['All'] + [str(i) for i in df.origin.unique()])
def update(attr, old, new):
all = pd.Series(True, index=df.index)
if select_cyl.value == 'All':
cond_cyl = all
else:
cond_cyl = df.cyl == int(select_cyl.value)
if select_ori.value == 'All':
cond_ori = all
else:
cond_ori = df.origin == int(select_ori.value)
filtered_df = df[cond_cyl & cond_ori]
hist, edges = histogram(filtered_df.hp, density=True, bins=20)
pdf = gaussian_kde(filtered_df.hp)
source_hist.data = {'top': hist, 'left': edges[:-1], 'right': edges[1:]}
source_kde.data = {'x': x, 'y': pdf(x)}
update(None, None, 'All')
select_ori.on_change('value', update)
select_cyl.on_change('value', update)
doc.add_root(column(select_ori, select_cyl, p))