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

Plotly图表按大洲分组Y轴并显示组标题的布局设置咨询

实现Y轴按大洲分组并显示大洲名称

Plotly没有直接配置Y轴分组的内置选项,需要通过数据预处理排序+自定义刻度+添加分隔线与注释来实现,具体步骤如下:

1. 数据预处理:按大洲分组排序国家

先保留国家对应的大洲信息,按大洲分组后对组内国家排序,确保Y轴上同大洲的国家连续排列:

import pandas as pd
import plotly.graph_objects as go
from plotly import data

df = data.gapminder()
df = df.loc[df.year.isin([1987, 2007])]

# 筛选目标国家并关联大洲信息,按人口排序
country_continent = (
    df.loc[df.year == 2007]
    .sort_values(by=["pop"], ascending=True)[["country", "continent"]]
    .drop_duplicates()
)[5:-10]

# 按大洲分组,整理每个大洲的国家列表
grouped_countries = country_continent.groupby("continent")["country"].apply(list).to_dict()

# 合并成按大洲排序的完整国家列表
sorted_countries = []
continent_order = list(grouped_countries.keys())
for continent in continent_order:
    sorted_countries.extend(grouped_countries[continent])

2. 重新构建可视化数据

按照排序后的国家列表生成绘图所需的x/y/颜色等数据:

data_dict = {"x": [], "y": [], "colors": [], "years": []}

for country in sorted_countries:
    data_dict["x"].extend(
        [
            df.loc[(df.year == 1987) & (df.country == country)]["pop"].values[0],
            df.loc[(df.year == 2007) & (df.country == country)]["pop"].values[0],
            None,
        ]
    )
    data_dict["y"].extend([country, country, None])
    data_dict["colors"].extend(["cyan", "darkblue", "white"])
    data_dict["years"].extend(["1987", "2007", None])

3. 配置布局:添加分组分隔线与大洲名称注释

通过layout.shapes添加分组间的水平分隔线,用layout.annotations在每个分组顶部插入大洲名称,同时绑定Y轴刻度与排序后的国家:

fig = go.Figure(
    data=[
        go.Scatter(
            x=data_dict["x"],
            y=data_dict["y"],
            mode="lines",
            marker=dict(color="grey"),
        ),
        go.Scatter(
            x=data_dict["x"],
            y=data_dict["y"],
            text=data_dict["years"],
            mode="markers",
            marker=dict(
                color=data_dict["colors"],
                symbol=["square", "circle", "circle"] * len(sorted_countries),
                size=16
            ),
            hovertemplate="""Country: %{y} <br> Population: %{x} <br> Year: %{text} <br><extra></extra>"""
        )
    ]
)

# 计算每个国家在Y轴的索引位置,用于定位分隔线和注释
y_pos = {country: idx for idx, country in enumerate(sorted_countries)}
shapes = []
annotations = []
current_pos = 0

for continent in continent_order:
    country_list = grouped_countries[continent]
    # 计算分组的起始、结束索引
    start_pos = current_pos
    end_pos = current_pos + len(country_list) - 1
    # 添加垂直显示的大洲名称注释,放在分组中间位置
    annotations.append(
        dict(
            xref="paper", x=0, y=(start_pos + end_pos)/2,
            text=f"<b>{continent}</b>",
            showarrow=False,
            font=dict(size=14),
            textangle=-90
        )
    )
    # 给除最后一个大洲外的分组添加底部分隔线
    if continent != continent_order[-1]:
        shapes.append(
            dict(
                type="line",
                xref="paper", x0=0, x1=1,
                yref="y", y0=end_pos + 0.5, y1=end_pos + 0.5,
                line=dict(color="black", width=2)
            )
        )
    current_pos += len(country_list)

# 更新布局参数
fig.update_layout(
    yaxis=dict(
        tickmode="array",
        tickvals=list(range(len(sorted_countries))),
        ticktext=sorted_countries,
        tickfont=dict(size=10)
    ),
    shapes=shapes,
    annotations=annotations,
    height=800  # 调整高度适配多分组显示
)

fig.show()

关键说明

  • 数据排序是分组显示的基础,必须保证同大洲国家在Y轴上连续排列
  • 用shapes绘制的水平分隔线可以清晰区分不同大洲分组
  • 垂直排版的大洲名称注释通过textangle=-90实现,放在分组中间位置更直观
  • Y轴刻度通过tickvals和ticktext绑定排序后的国家列表,确保对应关系准确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:15:24