如何用Python Shiny实现用户输入控制Plotly旭日图?
Python Shiny + Plotly 实现响应式旭日图(绑定用户输入)
问题根源
你遇到的JSON序列化错误,核心原因是直接传递了Shiny的响应式Value对象(比如input.my_num)给Plotly,而没有获取它的实时数值。Shiny的输入是响应式容器,必须通过input.my_num()(带括号调用)才能拿到当前的实际值,否则Plotly无法序列化这个响应式对象。
正确实现代码
下面是完整的可运行示例,实现单个数值输入控制旭日图参数,同时保留响应性:
from shiny import App, render, ui import plotly.express as px import pandas as pd # 构造旭日图基础数据 df = pd.DataFrame({ "level1": ["A", "A", "B", "B"], "level2": ["A1", "A2", "B1", "B2"], "value": [10, 10, 10, 10] }) app_ui = ui.page_fluid( # 数值输入控件,设置默认值、范围 ui.input_numeric("scale_factor", "调整数值缩放倍数", value=1, min=0.5, max=5, step=0.5), # 图表输出区域 ui.output_plotly("sunburst_plot") ) def server(input, output, session): @output @render.plotly def sunburst_plot(): # 关键:用()获取响应式输入的实时值 scale = input.scale_factor() # 根据输入值调整数据 scaled_df = df.assign(value=df["value"] * scale) # 生成旭日图 fig = px.sunburst( scaled_df, path=["level1", "level2"], values="value", title="响应式旭日图(可缩放数值)" ) return fig app = App(app_ui, server)
扩展至多输入控制
如果需要多个输入参数(比如同时控制不同层级的权重),只需要在UI中添加更多输入控件,然后在服务器端按需获取并处理即可:
# 扩展后的UI app_ui = ui.page_fluid( ui.input_numeric("scale_a", "A组缩放倍数", value=1, min=0.5, max=5, step=0.5), ui.input_numeric("scale_b", "B组缩放倍数", value=1, min=0.5, max=5, step=0.5), ui.output_plotly("sunburst_plot") ) def server(input, output, session): @output @render.plotly def sunburst_plot(): # 获取多个输入值 scale_a = input.scale_a() scale_b = input.scale_b() # 根据分组调整数值 scaled_df = df.copy() scaled_df.loc[scaled_df["level1"] == "A", "value"] *= scale_a scaled_df.loc[scaled_df["level1"] == "B", "value"] *= scale_b # 生成旭日图 fig = px.sunburst( scaled_df, path=["level1", "level2"], values="value", title="多输入控制的响应式旭日图" ) return fig
关键注意点
- 所有Shiny输入值的获取都必须带括号:
input.xxx(),这是Python Shiny和R Shiny的核心差异之一(R中直接用input$xxx即可)。 - 响应式计算要放在
@render.plotly装饰的函数内部,确保输入变化时图表自动更新。
内容的提问来源于stack exchange,提问作者Beavis
相关产品推荐
相关产品推荐

