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

如何在Python中旋转图表,将数值置于X轴、分类数据置于Y轴?

实现横向多索引柱状图的解决方案

关键修改说明

要把数值放在X轴、分类数据(Satellite/Reference)放在Y轴,只需要对原代码做以下核心调整:

  1. 将纵向柱状图改为横向(使用barh替代bar)
  2. 适配多索引标签的绘制逻辑,针对Y轴左侧重新计算标签位置和分隔线
  3. 修正原代码中的笔误(padas改为pandas)

修改后的完整代码

import pandas as pd
import matplotlib.pyplot as plt
from itertools import groupby
import numpy as np 
%matplotlib inline

# 创建带多级索引的示例DataFrame
Satellite  = ['Image fusion', 'Landsat 8 OLI', 'Sentinel 2A MSI']
Reference = ['Batur and Maktav, 2019', 'Cao et al., 2022', 'Krishnaraj and Honnasiddaiah, 2022', 'Pereira et al., 2020','Qian et al., 2022']
Type = ('In_situ', 'Remote_sensing')

index = pd.MultiIndex.from_tuples([('Image fusion','Batur and Maktav, 2019'),('Landsat 8 OLI','Cao et al., 2022'),('Landsat 8 OLI','Krishnaraj and Honnasiddaiah, 2022'),('Landsat 8 OLI','Pereira et al., 2020'), ('Sentinel 2A MSI','Qian et al., 2022')],
names=['Satellite', 'Reference'])
values = np.array([[8.29, 8],[7.56, 7.5],[7.8, 7.9], [7.85, 8.165],[8.31, 8.9]])

df = pd.DataFrame(index=index)
df['In_situ'] = values[:,0]
df['Remote_sensing'] = values[:,1]   

def add_line(ax, ypos, xpos):
    # 调整线条方向,适配横向柱状图的Y轴分隔
    line = plt.Line2D([xpos - .1, xpos], [ypos, ypos],
                      transform=ax.transAxes, color='gray')
    line.set_clip_on(False)
    ax.add_line(line)

def label_len(my_index,level):
    labels = my_index.get_level_values(level)
    return [(k, sum(1 for i in g)) for k,g in groupby(labels)]

def label_group_bar_table(ax, df):
    xpos = -.1
    scale = 1./df.index.size
    # 倒序处理多索引层级,从外层到内层
    for level in range(df.index.nlevels)[::-1]:
        pos = 0
        for label, rpos in label_len(df.index,level):
            lypos = (pos + .5 * rpos)*scale
            # 在Y轴左侧添加标签,水平对齐方式改为右对齐
            ax.text(xpos, lypos, label, ha='right', va='center', transform=ax.transAxes)
            add_line(ax, pos*scale, xpos)
            pos += rpos
        add_line(ax, pos*scale , xpos)
        xpos -= .1 

# 绘制横向柱状图
ax = df.plot(kind='barh', stacked=False)
# 隐藏默认的Y轴刻度标签
ax.set_yticklabels('')
# 隐藏默认的Y轴标题
ax.set_ylabel('')
# 调用修改后的标签绘制函数
label_group_bar_table(ax, df)
# 调整布局避免标签被截断
plt.tight_layout()
plt.show()

代码细节解释

  • 横向柱状图切换:kind='barh'会将柱状图旋转90度,数值自动映射到X轴,分类项映射到Y轴
  • 标签函数适配:
    • 修改add_line函数,将竖线改为横线,适配Y轴方向的分类分隔
    • label_group_bar_table中调整坐标计算逻辑,把多层索引标签放在Y轴左侧,水平对齐方式设为右对齐
    • 逐步左移xpos,为外层索引标签留出空间
  • 布局优化:plt.tight_layout()自动调整图表元素位置,避免标签被画布边缘截断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:11:01