Plotly热力图滑动切换时在悬浮框添加并更新额外字段
Plotly热力图滑块切换时动态更新悬浮框的A/B/C列数据
需要用Plotly绘制带滑块切换分类的热力图,当前已实现滑块切换及基础悬浮信息,但无法在悬浮框中动态显示A、B、C列的数据。原代码如下:
# create Pandas dataframe df = pd.DataFrame({'x_label': [1,2,3,1,2,3,1,2,3], 'y_label': [3,4,5,3,4,5,3,4,5], 'z_label':[6,7,8,9,10,11,12,13,14], 'A': [10, 11, 12,13,14,15,16,17,18], 'B': [10, 12, 14,16,18,20,22,24,26], 'C': [12, 14, 16,18,20,22,24,26,28], 'slider':['a','a','a','b','b','b','c','c','c']}) # create list of dataframes where each dataframe is a filtered dataframe based on the selected slider category multi_dfs = [df[df['slider'] == s] for s in df['slider'].unique()] # create and name each frame in the heatmap based on the slider name frames = [ go.Frame(data=go.Heatmap(z=df['z_label'], x=df['x_label'], y=df['y_label']), name=df['slider'].iloc[0], ) for i, df in enumerate(multi_dfs) ] # plot the heatmap figure fig = go.Figure(data=frames[0].data, frames=frames).update_layout( # iterate over frames to generate slider steps sliders=[{"active":1, "currentvalue":{"prefix": "slider: "}, "steps": [{"args": [[f.name],{"frame": {"duration": 0, "redraw": True}, "mode": "immediate",},], "label": f.name, "method": "animate",} for f in frames],}] ) # update hovertemplate labels and information fig.update_traces( hovertemplate="X Custom Label: %{x}" "<br>Y Custom Label: %{y}" "<br>Z Custom Label: %{z}<extra></extra>" )
解决方案
问题核心是原代码的Heatmap未传递A/B/C的自定义数据,导致悬浮框无法获取这些值。修改步骤如下:
- 在每个动画帧的
go.Heatmap中添加customdata参数,将A、B、C列数据以二维数组形式传入(每一行对应热力图的一个点) - 在
hovertemplate中通过%{customdata[0]}、%{customdata[1]}、%{customdata[2]}分别调用A、B、C的值
修改后的完整代码:
import pandas as pd import plotly.graph_objects as go # 创建数据框 df = pd.DataFrame({'x_label': [1,2,3,1,2,3,1,2,3], 'y_label': [3,4,5,3,4,5,3,4,5], 'z_label':[6,7,8,9,10,11,12,13,14], 'A': [10, 11, 12,13,14,15,16,17,18], 'B': [10, 12, 14,16,18,20,22,24,26], 'C': [12, 14, 16,18,20,22,24,26,28], 'slider':['a','a','a','b','b','b','c','c','c']}) # 按slider分类拆分数据框 multi_dfs = [df[df['slider'] == s] for s in df['slider'].unique()] # 创建动画帧:每个帧的Heatmap包含customdata传递A/B/C frames = [ go.Frame( data=go.Heatmap( z=subset['z_label'], x=subset['x_label'], y=subset['y_label'], # 将A、B、C转为二维数组,每个元素对应一个点的三个值 customdata=subset[['A', 'B', 'C']].values ), name=subset['slider'].iloc[0], ) for subset in multi_dfs ] # 初始化图表 fig = go.Figure(data=frames[0].data, frames=frames) # 添加滑块布局 fig.update_layout( sliders=[{ "active": 1, "currentvalue": {"prefix": "slider: "}, "steps": [ { "args": [[f.name], {"frame": {"duration": 0, "redraw": True}, "mode": "immediate"}], "label": f.name, "method": "animate" } for f in frames ] }] ) # 更新悬浮模板:加入A/B/C的动态数据 fig.update_traces( hovertemplate=( "X Custom Label: %{x}<br>" "Y Custom Label: %{y}<br>" "Z Custom Label: %{z}<br>" "A: %{customdata[0]}<br>" "B: %{customdata[1]}<br>" "C: %{customdata[2]}<extra></extra>" ) ) fig.show()
关键说明
customdata接收二维数组,每一行对应热力图中一个点的A、B、C值,滑块切换时,当前帧的customdata会自动替换原数据,实现动态更新- 悬浮模板中通过索引调用
customdata的元素,即可显示对应列的实时数值
内容的提问来源于stack exchange,提问作者finstats
相关产品推荐
相关产品推荐

