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

如何在Plotly Scattergeo美国地图中使用离散色阶

这确实是处理极端值可视化时的痛点——当少数城市的数值远远超出其他样本时,连续色阶会让大部分数据的颜色差异被“压缩”,根本看不清细节。离散色阶通过把数值划分为不同区间并分配独立颜色,能完美解决这个问题。下面我给你两种在Plotly中实现的实用方案,覆盖Express和Graph Objects两种常用方式:

方案1:用Plotly Express快速实现离散色阶

Express的语法更简洁,适合快速可视化。核心思路是先把连续的数值字段转换成离散的分类字段,再指定每个分类的颜色:

import plotly.express as px
import pandas as pd

# 模拟你的城市数据(替换成你的真实数据即可)
city_data = pd.DataFrame({
    "City": ["New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia"],
    "EventCount": [50000, 8200, 6700, 4300, 2900, 1800],
    "Lat": [40.7128, 34.0522, 41.8781, 29.7604, 33.4484, 39.9526],
    "Lon": [-74.0060, -118.2437, -87.6298, -95.3698, -112.0740, -75.1652]
})

# 自定义离散区间和对应标签(根据你的数据分布调整)
bins = [0, 2000, 5000, 20000, 50000]
category_labels = ["0-2000", "2001-5000", "5001-20000", "20001-50000"]

# 给数据添加分类列
city_data["EventCategory"] = pd.cut(
    city_data["EventCount"], 
    bins=bins, 
    labels=category_labels, 
    include_lowest=True  # 确保最小值被包含在第一个区间
)

# 自定义颜色映射(选你喜欢的配色)
color_map = {
    "0-2000": "#e5f5f9",
    "2001-5000": "#99d8c9",
    "5001-20000": "#2ca25f",
    "20001-50000": "#006d2c"
}

# 绘制带离散色阶的地图(这里用散点地图,换成choropleth同理)
fig = px.scatter_mapbox(
    city_data,
    lat="Lat",
    lon="Lon",
    color="EventCategory",
    color_discrete_map=color_map,
    size="EventCount",  # 可选:用点的大小辅助区分数值高低
    hover_name="City",
    hover_data={"EventCount": True, "EventCategory": False},  # 悬停时显示具体数值
    mapbox_style="carto-positron",
    zoom=3
)

fig.update_layout(title="美国城市事件发生次数(离散色阶)")
fig.show()

为什么这么做?

通过pd.cut把连续的EventCount转成离散分类后,每个区间对应固定颜色,纽约的50000会被分到最高档,而其他城市的区间颜色差异清晰可见,不会被极端值掩盖。如果你的数据分布不均匀,也可以用pd.qcut按分位数自动划分区间,比如pd.qcut(city_data["EventCount"], q=4, labels=category_labels),这样每个区间的样本量更均衡。

方案2:用Plotly Graph Objects实现更灵活的离散色阶

如果你需要更精细控制色条、标记样式等,Graph Objects是更好的选择。这里直接定义离散的颜色刻度映射:

import plotly.graph_objects as go
import pandas as pd

# 同样使用模拟数据
city_data = pd.DataFrame({
    "City": ["New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia"],
    "EventCount": [50000, 8200, 6700, 4300, 2900, 1800],
    "Lat": [40.7128, 34.0522, 41.8781, 29.7604, 33.4484, 39.9526],
    "Lon": [-74.0060, -118.2437, -87.6298, -95.3698, -112.0740, -75.1652]
})

# 定义区间和对应颜色(区间边界对应数值的比例,比如0对应0,2000/50000=0.04,以此类推)
color_scale = [
    [0, "#e5f5f9"],
    [2000/50000, "#99d8c9"],
    [5000/50000, "#2ca25f"],
    [20000/50000, "#006d2c"],
    [1, "#006d2c"]  # 最高区间的上限对应1(即50000)
]

fig = go.Figure(go.Scattermapbox(
    lat=city_data["Lat"],
    lon=city_data["Lon"],
    mode="markers",
    marker=dict(
        size=city_data["EventCount"]/1000,  # 缩放点的大小,避免纽约的点太大
        color=city_data["EventCount"],
        colorscale=color_scale,
        cmin=0,
        cmax=50000,
        colorbar=dict(
            tickvals=[1000, 3500, 12500, 35000],  # 色条刻度位置(对应每个区间的中间值)
            ticktext=["0-2000", "2001-5000", "5001-20000", "20001-50000"],  # 刻度标签
            title="事件次数",
            thickness=15
        ),
        showscale=True
    ),
    # 悬停时显示的内容
    text=[f"{city}<br>事件次数: {count}" for city, count in zip(city_data["City"], city_data["EventCount"])]
))

fig.update_layout(
    mapbox_style="carto-positron",
    zoom=3,
    title="美国城市事件发生次数(离散色阶)"
)

fig.show()

这个方案的优势:

不需要预先转换数据为分类字段,直接通过colorscale定义离散区间的颜色映射,色条的样式也能完全自定义,适合需要高度定制化的可视化场景。

额外小技巧:

  • 如果是绘制 choropleth 地图,两种方案的逻辑完全通用:Express中用color_discrete_map,Graph Objects中设置colorscale为离散区间即可。
  • 可以给极端值区间设置更醒目的颜色(比如红色),让它在图中一眼就能被识别出来。

内容的提问来源于stack exchange,提问作者evangelist_17

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:44:23