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

在ggplot中实现按区域分组且内部分降序的条形图需求问询

通用条形图实现方案(按Region分组、Count降序排列)

我来给你提供一个完全通用的实现方案,用Python的pandas和matplotlib就能搞定,完美符合你的所有要求——不用填充颜色区分Region,支持任意数量的Region和国家,同一Region的条形相邻且按Count降序排列,所有条形宽度一致、高度共用同一刻度。

核心思路

  • 先对数据做预处理:按Region分组,每个组内的国家按Count从高到低排序,然后把所有组拼接起来,确保同一Region的国家挨在一起。
  • 不用填充色区分Region的话,我们可以用条形边框颜色+分组分隔线,或者**条形填充图案(hatch)**来做视觉区分,效果同样清晰。
  • 所有逻辑都是动态的,不管你加多少Region或者国家,代码都能自动适配。

完整代码示例

import pandas as pd
import matplotlib.pyplot as plt

# 这里可以替换成你自己的真实数据,只要结构是Site/Region/Count就行
data = pd.DataFrame({
    'Site': ['USA', 'Canada', 'Mexico', 'UK', 'France', 'Germany', 'Japan', 'China', 'South Korea'],
    'Region': ['North America', 'North America', 'North America', 'Europe', 'Europe', 'Europe', 'Asia', 'Asia', 'Asia'],
    'Count': [120, 90, 75, 100, 85, 95, 150, 130, 110]
})

# 关键预处理:按Region分组,组内按Count降序排序,保留Region的原始顺序
sorted_data = data.groupby('Region', sort=False).apply(lambda x: x.sort_values('Count', ascending=False)).reset_index(drop=True)

# 记录每个Region在排序后数据中的起始/结束位置,方便后续分组设置样式
region_boundaries = sorted_data.groupby('Region').agg(
    start_idx=('Site', 'idxmin'),
    end_idx=('Site', 'idxmax')
).reset_index()

# 创建画布和轴对象
fig, ax = plt.subplots(figsize=(10, 6))

# 绘制所有条形,统一宽度
bar_width = 0.8
x_positions = range(len(sorted_data))
bars = ax.bar(x_positions, sorted_data['Count'], width=bar_width, edgecolor='black')

# 方案1:用边框颜色区分Region(替代填充色)
# 可以根据Region数量扩展颜色列表
region_colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
for idx, region in enumerate(region_boundaries['Region']):
    start = region_boundaries.loc[idx, 'start_idx']
    end = region_boundaries.loc[idx, 'end_idx']
    # 给当前Region的所有条形设置统一的边框颜色和粗细
    for bar in bars[start:end+1]:
        bar.set_edgecolor(region_colors[idx % len(region_colors)])
        bar.set_linewidth(2)

# 添加Region之间的分隔虚线,强化分组视觉效果
for end_idx in region_boundaries['end_idx'][:-1]:
    ax.axvline(x_positions[end_idx] + bar_width/2 + 0.2, color='gray', linestyle='--', alpha=0.7)

# 设置x轴标签为国家名称,旋转避免重叠
ax.set_xticks(x_positions)
ax.set_xticklabels(sorted_data['Site'], rotation=45, ha='right')

# 添加标题和轴标签
ax.set_title('Count by Country (Grouped by Region, Sorted by Count)', fontsize=12)
ax.set_ylabel('Count', fontsize=10)
ax.set_xlabel('Country', fontsize=10)

# 在每个条形上方添加数值标签,更直观
for bar in bars:
    height = bar.get_height()
    ax.text(bar.get_x() + bar.get_width()/2., height,
            f'{int(height)}',
            ha='center', va='bottom', fontsize=9)

# 调整布局,防止标签被截断
plt.tight_layout()
plt.show()

替代区分方案(不用颜色)

如果你连边框颜色都不想用,还可以用**填充图案(hatch)**来区分Region,把上面的边框颜色部分替换成这段代码就行:

# 方案2:用填充图案区分Region
hatch_patterns = ['///', '\\\\\\', 'xxx', '+++']
for idx, region in enumerate(region_boundaries['Region']):
    start = region_boundaries.loc[idx, 'start_idx']
    end = region_boundaries.loc[idx, 'end_idx']
    for bar in bars[start:end+1]:
        bar.set_hatch(hatch_patterns[idx % len(hatch_patterns)])
        bar.set_edgecolor('black')  # 保持边框统一黑色

通用性说明

  • 不管你有多少个Region或者国家,只要你的数据包含Site(国家)、Region(所属区域)、Count(数值)这三列,直接替换代码里的data部分就行,核心逻辑完全不用改。
  • 排序、分组、样式设置都是动态计算的,自动适配数据规模。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:14:23