交互式Plotly Int滑块

3

大家好,我是一个Python、Plotly和Jupyter Notebook的新手。我想使用一个滑动条来选择天数范围,以此为查询条件创建一张图表。我的问题在于,我希望图表能够在与滑动条交互时自动更新,而不必重新运行查询和图表创建代码。我的代码如下:

slider = widgets.IntSlider()
display(slider)
sliderVal = slider.value

df = pd.read_sql(f"""
SELECT CASE WHEN SiteID LIKE 3 THEN 'BLAH' 
        WHEN SiteID LIKE 4 THEN 'BLAHBLAH' 
        END AS Website, 
        COUNT(1) AS Count
FROM            viewName
WHERE        (TimeStamp > DATEADD(DAY, -{sliderVal}, GETDATE()))
GROUP BY SiteId
ORDER BY Count DESC
           """, conn)

data = [go.Bar(x=df.Website, y=df.Count)]
layout = go.Layout(
    xaxis=dict(
        title='Website'),
    yaxis=dict(
        title='Exception count'),
    title=f'Number of exceptions per user in the last {sliderVal} days')
chart = go.Figure(data=data, layout=layout, )
py.iplot(chart, filename='WebExceptions')

提前感谢!


下次请尝试提供一个可重现的示例,包括最小的数据集,以便人们可以在需要时运行您的示例。这样做可以更快地获得更精确的答案。 - byouness
1个回答

2

如果您不想重新运行查询,那么您的数据框 df 必须包含您希望 intslider 小部件采用的所有值的结果,然后与小部件链接的函数将仅过滤数据并使用新过滤的数据重新绘制图表。

以下是一个带有虚假数据的示例:

import ipywidgets as widgets
import plotly.offline as py
import plotly.graph_objs as go
import pandas as pd
py.init_notebook_mode(connected = True)

# Dummy data, to be replaced with your query result for the range of sliderVal
df = pd.DataFrame({'Days': [1] * 3 + [2] * 4 + [3] * 5,
                  'Website': [1,2,3, 4,5,6,7, 8,9,10,11,12],
                  'Count': [10,5,30, 15,20,25,12, 18,17,30,23,27]})

def update_plot(sliderVal):
    filtered_df = df.query('Days== ' + str(sliderVal))
    data = [go.Bar(x = filtered_df.Website,
                   y = filtered_df.Count)]
    layout = go.Layout(
        xaxis = dict(title = 'Website'),
        yaxis = dict(title = 'Exception count'),
        title = f'Number of exceptions per user in the last {sliderVal} days')
    chart = go.Figure(data = data, layout = layout, )
    py.iplot(chart, filename = 'WebExceptions')

# links an IntSlider taking values between 1 and 3 to the update_plot function
widgets.interact(update_plot, sliderVal = (1, 3))

下面是 sliderVal = 2 时的结果:

输入图像描述


我是否需要像在虚拟数据部分中所做的那样,在静态df中对查询结果进行排序?如果不需要,那么在df.query中我应该使用哪个列代替“Days”? - gcpreston
排序?你是说存储吗?你需要检索你希望 sliderVal 覆盖的值的结果,这样移动 sliderVal 将仅从数据框中过滤并显示结果,而不是从数据库中获取结果...我希望这很清楚。 - byouness
抱歉 @byouness ,我是指存储。如果“df”是从类似于我上面执行的查询中填充的,而不是手动填充的虚拟数据“df”,这仍然可以工作吗? 如果是这样,我应该使用什么代替数组“Days”呢? 对于这些愚蠢的问题,再次表示抱歉。 - gcpreston
很简单:您不想在每次小部件的值更改时查询数据库,因此必须将数据存储在内存中(在您的df中)。假设您想要覆盖1到3之间的值,最简单的方法是使用WHERE (TimeStamp > DATEADD(DAY,-1,GETDATE()))运行3次查询,然后是...DATEADD(DAY,-2,GETDATE())),然后是...DATEADD(DAY,-3,GETDATE())),并将所有这些结果放入您的数据框中,第一组中的Days=1,第二组中的Days=2,第三组中的days=3。您可以将这3个查询合并为一个SQL查询,但那是另一个问题。我希望这有所帮助。 - byouness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接