You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python底图上为类3D柱状图添加数值标签

如何在Python底图上为类3D柱状图添加数值标签

看起来你已经把HSA区域底图和分类柱状图的核心逻辑都搞定了,就差给每个柱子顶部加上清晰的数值标签对吧?我仔细看了你的代码,数值标签不显示的问题主要出在文本标注的Scattermapbox Trace配置上,咱们来针对性调整,同时优化一些细节让可视化效果更专业。

核心问题分析与修改方案

你当前用mode="markers+text"来添加标签,但标记点的设置、文本模式的选择以及标签位置的计算都有优化空间。下面是调整后的完整代码,重点修改了数值标签的绘制逻辑,同时补充了实用的细节优化:

import plotly.graph_objects as go

fig = go.Figure()

# 底图部分保持原有逻辑不变
fig.add_trace(go.Choroplethmapbox(
    geojson=nys_hsa.geometry.__geo_interface__,
    locations=nys_hsa.index,
    z=[0]*len(nys_hsa), # 底图用dummy值
    colorscale=[[0, "white"], [1, "white"]],
    showscale=False,
    marker_opacity=0.2,
    marker_line_width=1,
    marker_line_color='black',
    hoverinfo="skip", # 底图不需要hover
    name="HSA Zones"
))

bar_offset = 0.05
bar_colors = {'Major': 'red', 'Moderate': 'orange', 'Minor': 'green'}
bar_height_scale = 0.05 # 百分比转纬度度数的缩放系数
bar_line_width = 10 # 加粗柱子提升辨识度
legend_flags = {'Major': False, 'Moderate': False, 'Minor': False}

for _, row in nys_hsa.iterrows():
    lon = row['lon']
    lat = row['lat']
    for i, category in enumerate(['Major', 'Moderate', 'Minor']):
        offset = (i - 1) * bar_offset
        value = row[category]
        
        # 跳过数值为0的柱子,减少画面杂乱感
        if value == 0:
            continue
            
        bar_height = value * bar_height_scale
        
        # 绘制垂直柱状图(保留原有逻辑)
        fig.add_trace(go.Scattermapbox(
            mode="lines",
            lon=[lon + offset, lon + offset],
            lat=[lat, lat + bar_height],
            line=dict(width=bar_line_width, color=bar_colors[category]),
            hoverinfo="text",
            text=f"{row['RegionName']}<br>{category}: {value:.2f}%",
            showlegend=not legend_flags[category],
            name=category
        ))
        legend_flags[category] = True
        
        # 🔧 修改后的数值标签绘制逻辑
        # 动态计算标签偏移:小柱子用固定小偏移,大柱子用比例偏移,避免重叠
        label_offset = max(0.01, bar_height * 0.1)
        label_lat = lat + bar_height + label_offset
        
        fig.add_trace(go.Scattermapbox(
            mode="text",  # 直接使用text模式,无需依赖marker锚定
            lon=[lon + offset],
            lat=[label_lat],
            text=[f"{value:.1f}%"],
            textposition="middle center",  # 标签中心对齐柱子顶部
            textfont=dict(
                size=12, 
                color=bar_colors[category], 
                family="Arial",
                weight="bold" # 加粗文本提升可读性
            ),
            # 添加文本背景和边框,在复杂地图上更清晰
            textbackgroundcolor="white",
            textbordercolor="black",
            textborderwidth=1,
            showlegend=False,
            hoverinfo="skip"
        ))

# 布局部分保持原有设置
fig.update_layout(
    title="New York State HSA Zones with Risk Bar Charts",
    mapbox_style="carto-positron",
    mapbox_zoom=5.5,
    mapbox_center={"lat": nys_hsa['lat'].mean(), "lon": nys_hsa['lon'].mean()},
    height=800,
    margin=dict(l=0, r=0, b=0, t=50),
    legend=dict(
        title="Risk Level",
        orientation="v",
        yanchor="top",
        y=0.95,
        xanchor="right",
        x=1.02,
        bgcolor="rgba(255,255,255,0.8)",
        bordercolor="black",
        borderwidth=1,
        itemsizing="trace"
    ),
    showlegend=True
)

fig.show()

关键修改点说明

  1. 文本模式优化:把mode="markers+text"改为mode="text",直接绘制文本,不需要依赖marker锚定,彻底避免不必要的视觉干扰。
  2. 动态标签偏移:根据柱子高度计算标签垂直偏移,小柱子用固定小偏移(0.01度纬度),大柱子用高度的10%作为偏移,确保标签既不与柱子重叠,也不会离得太远。
  3. 可读性提升:给文本添加加粗效果、白色背景和黑色边框,在地图背景下辨识度大幅提升;同时把textposition改为"middle center",让标签完美对齐柱子顶部。
  4. 冗余元素过滤:添加if value == 0: continue判断,自动跳过数值为0的柱子和标签,减少画面杂乱感。

额外调试建议

如果修改后标签还是不显示,可以检查这几个点:

  • 临时调大mapbox_zoom聚焦某个区域,确认label_lat的计算是否超出地图显示范围;
  • 检查文本颜色是否和背景冲突(当前用柱子同色+白色背景,基本不会有问题);
  • 通过print(len(fig.data))确认每个标签trace都被正确添加,数量是否符合预期。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:24:30