Google Colab中使用Plotly搭配下拉控件的图表无法显示问题
问题原因
- 核心原因是Google Colab对
go.FigureWidget的适配与原生Jupyter Notebook存在差异,FigureWidget依赖的双向实时通信机制在Colab中默认未完全启用,导致嵌入ipywidgets组件的图表无法正常渲染。 - 你配置的
pio.renderers.default = 'colab'仅适配普通go.Figure调用show()的渲染场景,不兼容嵌入ipywidgets的FigureWidget渲染逻辑。 - 测试用的简单Plotly代码可正常显示,是因为未用到
FigureWidget和ipywidgets组件,走的是Colab原生支持的静态渲染路径,所以不受兼容问题影响。
解决方案
方案1:使用Plotly内置下拉菜单(无额外依赖,兼容性最优)
直接采用Plotly自带的updatemenus属性实现下拉切换功能,不需要引入ipywidgets,修改后代码在Colab可直接运行:
import plotly.graph_objects as go import pandas as pd df = pd.DataFrame() df['category'] = ['G1', 'G1', 'G1', 'G1','G1', 'G1','G1', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2'] df['date'] = ['2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30', '2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30'] df['col1'] = [54, 34, 65, 67, 23, 34, 54, 23, 67, 24, 64, 24, 45, 89] df['col2'] = round(df['col1'] * 0.85) x = 'date' y1 = 'col1' y2 = 'col2' fig = go.Figure() # 初始显示所有数据 aux_df = df[df.category.isin(['G1','G2'])] fig.add_trace(go.Scatter(x=aux_df[x], y=aux_df[y1], mode='lines', name='col 1', marker_color='blue')) fig.add_trace(go.Scatter(x=aux_df[x], y=aux_df[y2], mode='lines', name='col 2', marker_color='yellow')) # 配置下拉菜单 fig.update_layout( title='my plot', xaxis=dict( title='Date', type='date', tickformat='%Y-%m-%d', ticklen=5, titlefont=dict( family='Old Standard TT, serif', size=20, color='black' ) ), yaxis=dict( title='values', ticklen=5, titlefont=dict( family='Old Standard TT, serif', size=20, color='black' ) ), updatemenus=[ dict( buttons=list([ dict( label='All', method='update', args=[{'x': [df[df.category.isin(['G1','G2'])][x], df[df.category.isin(['G1','G2'])][x]], 'y': [df[df.category.isin(['G1','G2'])][y1], df[df.category.isin(['G1','G2'])][y2]]} ] ), dict( label='G1', method='update', args=[{'x': [df[df.category.isin(['G1'])][x], df[df.category.isin(['G1'])][x]], 'y': [df[df.category.isin(['G1'])][y1], df[df.category.isin(['G1'])][y2]]} ] ), dict( label='G2', method='update', args=[{'x': [df[df.category.isin(['G2'])][x], df[df.category.isin(['G2'])][x]], 'y': [df[df.category.isin(['G2'])][y1], df[df.category.isin(['G2'])][y2]]} ] ) ]), direction='down', showactive=True, ) ] ) fig.show()
方案2:保留ipywidgets写法,开启Colab自定义组件支持
如果需要保留原有ipywidgets的实现逻辑,只需要在代码开头添加Colab自定义组件管理器启用代码,删除原有渲染器配置即可:
import plotly.graph_objects as go import ipywidgets as w from IPython.display import display import pandas as pd # 新增:启用Colab自定义组件支持 from google.colab import output output.enable_custom_widget_manager() df = pd.DataFrame() df['category'] = ['G1', 'G1', 'G1', 'G1','G1', 'G1','G1', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2'] df['date'] = ['2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30', '2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30'] df['col1'] = [54, 34, 65, 67, 23, 34, 54, 23, 67, 24, 64, 24, 45, 89] df['col2'] = round(df['col1'] * 0.85) x = 'date' y1 = 'col1' y2 = 'col2' trace1 = { 'x': df[x], 'y': df[y1], 'type': 'scatter', 'mode': 'lines', 'name':'col 1', 'marker': {'color': 'blue'} } trace2={ 'x': df[x], 'y': df[y2], 'type': 'scatter', 'mode': 'lines', 'name':'col 2', 'marker': {'color': 'yellow'} } data = [trace1, trace2] layout=dict( title='my plot', xaxis=dict( title='Date', type='date', tickformat='%Y-%m-%d', ticklen=5, titlefont=dict( family='Old Standard TT, serif', size=20, color='black' ) ), yaxis=dict( title='values', ticklen=5, titlefont=dict( family='Old Standard TT, serif', size=20, color='black' ) ) ) fig = go.FigureWidget(data=data, layout=layout) def update_fig(change): aux_df = df[df.category.isin(change['new'])] with fig.batch_update(): for trace, column in zip(fig.data, [y1, y2]): trace.x = aux_df[x] trace.y = aux_df[column] drop = w.Dropdown(options=[ ('All', ['G1', 'G2']), ('G1', ['G1']), ('G2', ['G2']), ]) drop.observe(update_fig, names='value') display(w.VBox([drop, fig]))
内容的提问来源于stack exchange,提问作者Navya
相关产品推荐
相关产品推荐

