Plotly树形图(Treemap)仅在子节点显示悬浮信息(Hoverinfo)的实现方案咨询
解决Plotly Treemap父节点比率指标求和的问题
针对你遇到的两个需求,我分别给出具体的实现方案:
1. 仅子节点显示悬浮信息,父节点隐藏
要实现这个效果,我们可以利用Plotly的selector功能,针对不同层级的节点设置不同的悬浮信息规则。treemap的节点层级从0开始计数,对应你定义的path顺序:world是level 0,continent是level 1,country是level 2(子节点)。
先将所有节点的悬浮信息设为隐藏,再单独给最底层的子节点开启悬浮显示:
import pandas as pd import plotly.express as px df = pd.DataFrame({'world':['world']*4, 'continent':['SA','SA','NA','NA'], 'country':['Brazil','Uruguay','USA','Canada'], 'total_cases_per_100':[6,1,12,8]}) fig = px.treemap(df, path=['world','continent','country'],values='total_cases_per_100') # 先隐藏所有节点的悬浮信息 fig.update_traces(hoverinfo='none') # 单独为子节点(level=2)开启悬浮信息,显示指标值 fig.update_traces(hoverinfo='value', selector={'level': 2}) fig.show()
这样操作后,只有国家级别的子节点会在悬浮时显示total_cases_per_100的值,大洲和世界节点不会显示任何悬浮信息。
2. 用父节点实际值替换自动求和值
如果需要保留父节点的悬浮信息,但替换成你已知的实际比率,有两种实现方式,取决于你是否需要保持treemap的面积逻辑:
方式一:重构DataFrame包含父节点数据
直接在数据源中加入父节点的行,指定对应的实际指标值,Plotly会直接使用这些值而非自动求和,同时treemap的面积会按照你提供的values计算:
import pandas as pd import plotly.express as px # 构造包含父节点实际值的完整数据集 # 这里假设world的实际比率是7,SA是3.5,NA是10,你可以替换成自己的真实数据 df_full = pd.DataFrame([ {"world": "world", "continent": None, "country": None, "total_cases_per_100": 7}, {"world": "world", "continent": "SA", "country": None, "total_cases_per_100": 3.5}, {"world": "world", "continent": "NA", "country": None, "total_cases_per_100": 10}, {"world": "world", "continent": "SA", "country": "Brazil", "total_cases_per_100": 6}, {"world": "world", "continent": "SA", "country": "Uruguay", "total_cases_per_100": 1}, {"world": "world", "continent": "NA", "country": "USA", "total_cases_per_100": 12}, {"world": "world", "continent": "NA", "country": "Canada", "total_cases_per_100": 8} ]) fig = px.treemap(df_full, path=['world','continent','country'], values='total_cases_per_100') fig.update_traces(hovertemplate=None, hoverinfo='value') fig.show()
方式二:保留原面积逻辑,仅替换悬浮显示值
如果你希望treemap的面积仍然按照子节点值的总和来展示,但悬浮时显示父节点的实际比率,可以通过自定义customdata和hovertemplate实现:
import pandas as pd import plotly.express as px df = pd.DataFrame({'world':['world']*4, 'continent':['SA','SA','NA','NA'], 'country':['Brazil','Uruguay','USA','Canada'], 'total_cases_per_100':[6,1,12,8]}) # 定义父节点的实际比率,键是节点的路径元组 parent_actual_values = { ('world',): 7, ('world', 'SA'): 3.5, ('world', 'NA'): 10 } fig = px.treemap(df, path=['world','continent','country'], values='total_cases_per_100') # 遍历每个节点,设置自定义的显示值 for trace in fig.data: for idx, node_id in enumerate(trace.ids): # 将节点ID拆分为路径元组 node_path = tuple(node_id.split('/')) # 根据路径匹配实际值 if node_path in parent_actual_values: trace.customdata[idx] = parent_actual_values[node_path] else: # 子节点使用原数据的指标值 trace.customdata[idx] = df.loc[df['country'] == node_path[-1], 'total_cases_per_100'].iloc[0] # 设置悬浮模板,显示自定义数据 fig.update_traces( hovertemplate='total_cases_per_100: %{customdata}', hoverinfo='none' ) fig.show()
这个方式下,treemap的面积还是和原代码一致(父节点面积是子节点的总和),但悬浮时会显示你指定的父节点实际比率,子节点显示原数值。
内容的提问来源于stack exchange,提问作者callmeanythingyouwant
相关产品推荐
相关产品推荐

