如何在python中创建一个交互式图,根据我单击的位置生成一个新图?

时间:2019-04-17 07:34:07

标签: python matplotlib plotly bokeh

我拥有每个月和不同类别产品的商店销售数据。

说我有一个跨各方向的商店和月份销售量的热图。

现在,当我在与特定商店和月份相对应的位置单击热图时,我需要生成一个新的条形图,其中显示该月和商店中每个类别的销售量。

我在SAS VA中做了类似的事情。我相信它称为互动效应。

我已经尝试搜索matplotlib的文档,但没有得到任何有用的信息。

1 个答案:

答案 0 :(得分:2)

这里是一个示例,说明如何在Bokeh v1.1.0中做到这一点

from bokeh.plotting import figure, show
from bokeh.models import TapTool, CustomJS, ColumnDataSource, Row, ColorBar, LinearColorMapper, BasicTicker
from bokeh.models.sources import ColumnDataSource
from bokeh.transform import transform
from bokeh.palettes import Viridis256
import random

stores = ["store 1", "store 2", "store 3"]
months = ["january", "fabruary", "march"]
x = ["store 1", "store 2", "store 3", "store 1", "store 2", "store 3", "store 1", "store 2", "store 3"]
y = ["january", "january", "january", "fabruary", "fabruary", "fabruary", "march", "march", "march"]
colors = ["#0B486B", "#79BD9A", "#CFF09E", "#79BD9A", "#0B486B", "#79BD9A", "#CFF09E", "#79BD9A", "#0B486B" ]

p1 = figure(title = "Categorical Heatmap", tools = "tap", toolbar_location = None,
            x_range = stores, y_range = months)
p1.rect(x = x, y = y, color = colors, width = 1, height = 1)

categories = ['shoes', 'pants', 'suits']
category_sales = {}
for store in stores:
    category_sales[store] = {}
    for month in months:
        category_sales[store][month] = [random.choice([i for i in range(10000)]) for r in range(3)]

dummy_category_sales = [1000, 1100, 1200]
data = {'x': categories, 'y': dummy_category_sales}
source = ColumnDataSource(data)

p2 = figure(x_range = categories)
bars = p2.vbar(x = 'x', top = 'y', source = source, bottom = 0, width = 0.5)
bars.visible = False

code = '''if (cb_data.source.selected.indices.length > 0){
            bars.visible = true;
            selected_index = cb_data.source.selected.indices[0];    
            store = cb_data.source.data['x'][selected_index]
            month = cb_data.source.data['y'][selected_index]

            bars.data_source.data['y'] = category_sales[store][month]
            bars.data_source.change.emit(); 
        }'''

p1.select_one(TapTool).callback = CustomJS(args = dict(bars = bars, category_sales = category_sales), code = code)

plots = Row(p1, p2)
show(plots)

结果:

enter image description here