在子图中控制pandas Boxplot中的刻度标签对齐

时间:2016-02-08 04:45:41

标签: python pandas matplotlib

对于单个箱图,可以像这样控制刻度标签对齐:

import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline

fig,ax = plt.subplots()
df.boxplot(column='col1',by='col2',rot=45,ax=ax)
plt.xticks(ha='right')

这是必要的,因为当刻度标签很长时,如果刻度标签居中(默认行为),则无法读取绘图。

现在讨论多个子图的情况。 (对不起,我没有发布完整的代码示例)。我首先建立了主要人物:

fig,axarr = plt.subplots(ny,nx,sharex=True,sharey=True,figsize=(12,6),squeeze=False)

然后出现一个for循环,遍历所有子绘图轴并调用一个函数,在每个轴对象中绘制一个boxplot:

    for key,gr in grouped:
        ix = i/ny # Python 2
        iy = i%ny
        add_box_plot(gr,xcol,axarr[iy,ix])

,其中

def add_box_plot(gs,xcol,ax):
    gs.boxplot(column=xcol,by=keyCol,rot=45,ax=ax)

我还没有找到一种方法来获得正确对齐的刻度标签。

如果我添加         plt.xticks(ha='right') 在函数中的boxplot命令之后,只有 last 子图可以正确对齐标记(为什么?)。

2 个答案:

答案 0 :(得分:2)

  

如果我在函数中的boxplot命令之后添加plt.xticks(ha ='right'),只有最后一个子图可以正确对齐标记(为什么?)。

这是因为plt.xticks指的是最后一个活动轴。当您创建子图时,最后创建的图是活动的。然后直接访问轴opbjects (尽管它们在代码中被称为gsgr,无论这意味着什么)。但是,这不会更改活动轴。

解决方案1:

使用plt.sca()设置当前轴:

def add_box_plot(gs, xcol, ax):
    gs.boxplot(column=xcol, by=keyCol, rot=45, ax=ax)
    plt.sca(ax)
    plt.xticks(ha='right')

解决方案2:

改为使用Axes.set_xticklabels()

def add_box_plot(gs, xcol, ax):
    gs.boxplot(column=xcol,by=keyCol,rot=45,ax=ax)
    plt.draw()  # This may be required to update the labels
    labels = [l.get_text() for l in ax.get_xticklabels()]
    ax.set_xticklabels(labels, ha='right')

我不确定是否始终需要拨打plt.draw(),但如果我将其删除,我只会获得空标签。

答案 1 :(得分:0)

由于您使用的是mpl面向对象的界面,因此可以单独设置每个轴的刻度参数。

添加一行以在add_box_plot函数中设置xticklabels(在gs.boxplot之后)。与plt.xticks不同,您不能只提供set_xticklabels ha关键字,还需要您为其添加一个刻度标签列表。在这里,我们可以使用get_xticklabels抓取现有标签:

def add_box_plot(gs,xcol,ax):
    gs.boxplot(column=xcol,by=keyCol,rot=45,ax=ax)
    ax.set_xticklabels(ax.get_xticklabels(),ha='right')

这是一个显示此工作的最小示例:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# We'll create two subplots, to test out different alignments
fig,(ax1,ax2) = plt.subplots(2)

# A sample dataframe
df = pd.DataFrame(np.random.rand(10, 5), columns=['A', 'B', 'C', 'D', 'E'])

# Boxplot on first subplot
df.boxplot(ax=ax1)

# Boxplot on second subplot
df.boxplot(ax=ax2)

# Set xticklabels to right alignment
ax1.set_xticklabels(ax1.get_xticklabels(),ha='right')

# Set xticklabels to left alignment
ax2.set_xticklabels(ax2.get_xticklabels(),ha='left')

plt.show()

注意xticklabels在顶部子图上右对齐,在底部左对齐。

enter image description here