使用滑块小部件过滤和更新交互式散景可视化

问题描述

我是 Python 新手,我正在尝试使用散景创建一些交互式可视化。目前,我正在尝试使用散点图汇总分组数据,该散点图具有允许用户交换不同数据列的下拉功能

我创建了一个模拟数据框,类似于我作为 csv 加载的真实数据框:-

Device,Column1,Column2,Column3,Column4,Hour,Day
aaa,98,59,56,57,22,Day one
aaa,29,10,14,15,21,4,72,25,13,87,83,1,41,46,81,9,85,42,16,12,73,5,32,19,84,30,34,28,11,63,50,86,48,17,74,37,79,40,88,67,Day one
bbb,6,2,26,75,27,62,51,71,24,66,49,18,7,35,38,94,65,8,23,76,58,33,89,20,39,60,69,93,52,45,61,96,Day one
ccc,92,97,78,55,3,Day one
ddd,80,Day one
eee,44,70,54,31,82,Day two
eee,95,77,68,Day two
fff,36,43,64,90,53,91,Day two
ggg,Day two

这是我用来创建交互式绘图的 Python 代码:-

import numpy as np
import pandas as pd
from bokeh.layouts import column,row
from bokeh.models import  Select
from bokeh.plotting import figure,output_file,curdoc
from bokeh.palettes import Spectral5



####################################################

#this is the data I have provided above,as read in as a csv
dataset = pd.read_csv('exampledata.csv')



groupeddf=dataset.groupby(['Day','Hour','Device'])[['Column1','Column2','Column3','Column4']].mean()
groupeddf.head(10)
grouped_device_counts=dataset.groupby(['Day','Device']).size()#get counts of devices
grouped_device_counts=grouped_device_counts.reset_index()
grouped_device_counts = grouped_device_counts.rename(columns= {0: 'Count'})#works
#merge
group_device_summary=pd.merge(groupeddf,grouped_device_counts,on=['Day','Device'])#works
group_device_summary["color"] = np.where(group_device_summary["Count"] > 3,"orange","grey")
group_device_summary["alpha"] = np.where(group_device_summary["Count"] > 0,0.9,0.25)

group_device_summary.head(10)



# data cleanup
#group_device_summary.device_model = group_device_summary.device_model.astype(str)
#df.yr = group_device_summary.yr.astype(str)
#del df['name']
SIZES = list(range(6,3))
COLORS = Spectral5
N_SIZES = len(SIZES)
N_COLORS = len(COLORS)
columns = sorted(group_device_summary.columns)
discrete = [x for x in columns if group_device_summary[x].dtype == object]
continuous = [x for x in columns if x not in discrete]

#source=ColumnDataSource(columns)

#TOOLTIPS=[
 #   ("device","@device_model")
#]

def create_figure():
    xs = group_device_summary[x.value].values
    ys = group_device_summary[y.value].values
    x_title = x.value.title()
    y_title = y.value.title()

    kw = dict()
    if x.value in discrete:
        kw['x_range'] = sorted(set(xs))
    if y.value in discrete:
        kw['y_range'] = sorted(set(ys))
    kw['title'] = "%s vs %s" % (x_title,y_title)

    p = figure(height=600,width=800,tools='pan,Box_zoom,hover,reset',**kw)
    p.xaxis.axis_label = x_title
    p.yaxis.axis_label = y_title

    if x.value in discrete:
        p.xaxis.major_label_orientation = pd.np.pi / 4

    sz = 9
    if size.value != 'None':
        if len(set(group_device_summary[size.value])) > N_SIZES:
            groups = pd.qcut(group_device_summary[size.value].values,N_SIZES,duplicates='drop')
        else:
            groups = pd.Categorical(group_device_summary[size.value])
        sz = [SIZES[xx] for xx in groups.codes]

    c = "#31AADE"
    if color.value != 'None':
        if len(set(group_device_summary[color.value])) > N_COLORS:
            groups = pd.qcut(group_device_summary[color.value].values,N_COLORS,duplicates='drop')
        else:
            groups = pd.Categorical(group_device_summary[color.value])
        c = [COLORS[xx] for xx in groups.codes]

    p.circle(x=xs,y=ys,color=c,size=sz,line_color="white",alpha=0.6,hover_color='white',hover_alpha=0.5)

    return p


def update(attr,old,new):
    layout.children[1] = create_figure()


x = Select(title='X-Axis',value='Column1',options=columns)
x.on_change('value',update)

y = Select(title='Y-Axis',value='Column2',options=columns)
y.on_change('value',update)

size = Select(title='Size',value='None',options=['None'] + continuous)
size.on_change('value',update)

color = Select(title='Color',options=['None'] + discrete)
color.on_change('value',update)

controls = column(x,y,color,size,width=200)
layout = row(controls,create_figure())


output_file('scatter.html',title="Example")
curdoc().add_root(layout)
curdoc().title = "Crossfilter"#use curdoc to make it interactive
#show(layout)

预期结果

我想添加一个滑块小部件,它将通过“数据框”中的“小时”变量简单地更新可视化。类似于以下内容:-

slider = Slider(start=0,end=23,step=1,value=9,title='Hour')

谁能帮我将其实现到我现有的代码中?我已经做了很多相当脆弱的尝试来让它适当地过滤和绘制数据,但是可视化没有启动(给我白屏)或者绘图变得静态(无法更新)。>

我认为有一个简单的解决方案,非常感谢任何帮助:)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)