更改pandas boxplot子图中单个盒子的颜色

时间:2018-06-21 08:34:37

标签: python pandas dataframe matplotlib boxplot

这是参考以下问题,其中讨论了用于调整子图的标题和布局的选项: modify pandas boxplot output

我的要求是更改每个子图中各个框的颜色(如下图所示):

Something like this

以下是共享链接上可用的代码,用于调整子图的标题和轴属性:

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

df = pd.DataFrame(np.random.rand(140, 4), columns=['A', 'B', 'C', 'D'])
df['models'] = pd.Series(np.repeat(['model1','model2', 'model3', 'model4',     'model5', 'model6', 'model7'], 20))
bp = df.boxplot(by="models",layout=(4,1),figsize=(6,8))
[ax_tmp.set_xlabel('') for ax_tmp in np.asarray(bp).reshape(-1)]
fig = np.asarray(bp).reshape(-1)[0].get_figure()
fig.suptitle('New title here')
plt.show()

我尝试使用:     ax.set_facecolor('color') 属性,但无法成功获得预期结果。

我也尝试访问bp ['boxes'],但显然不可用。我需要对bp中存储的数据结构有所了解,以便访问子图中的各个框。

向前看

P.S:我知道seaborn。但是目前需要了解并使用df.boxplot实施。谢谢

2 个答案:

答案 0 :(得分:2)

要调整pandas.boxplot中框的颜色,必须稍微调整代码。首先,您必须告诉boxplot实际用颜色填充框。您可以通过指定patch_artist = True来完成此操作,如here所述。但是,您似乎无法指定颜色(默认为蓝色),如果我错了,请任何人纠正我。这意味着您之后必须更改颜色。幸运的是,pandas.boxplot提供了一个简单的选项,可以通过指定return_type = 'both' see here来获得箱图中的艺术家作为返回值。您得到的是一个pandas.Series,其键根据您的DataFrame列和值组成的元组,其中包含Axes实例,该实例在其上绘制了箱线图以及字典中箱线图的实际元素。我认为代码很容易解释:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch

df = pd.DataFrame(np.random.rand(140, 4), columns=['A', 'B', 'C', 'D'])

df['models'] = pd.Series(np.repeat(['model1','model2', 'model3', 'model4',     'model5', 'model6', 'model7'], 20))

bp_dict = df.boxplot(
    by="models",layout=(4,1),figsize=(6,8),
    return_type='both',
    patch_artist = True,
)

colors = ['b', 'y', 'm', 'c', 'g', 'b', 'r', 'k', ]
for row_key, (ax,row) in bp_dict.iteritems():
    ax.set_xlabel('')
    for i,box in enumerate(row['boxes']):
        box.set_facecolor(colors[i])

plt.show()

结果图如下:

result of the above code

希望这会有所帮助。

答案 1 :(得分:2)

尽管您命名了df.boxplot bp的返回,但实际上它是一个(n)个(数组)轴。检查轴以获取箱形图的各个部分很麻烦(但有可能)。

首先,为了能够使盒子的内部着色,您需要将盒子变成小块df.boxplot(..., patch_artist=True)

然后,您需要在轴上的所有艺术家中找到框。

# We want to make the 4th box in the second axes red    
axes[1].findobj(matplotlib.patches.Patch)[3].set_facecolor("red")

完整代码:

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

df = pd.DataFrame(np.random.rand(140, 4), columns=['A', 'B', 'C', 'D'])
df['models'] = pd.Series(np.repeat(['model1', 'model2', 'model3', 'model4',
                                    'model5', 'model6', 'model7'], 20))
axes = df.boxplot(by="models", layout=(len(df.columns)-1,1), figsize=(6,8), patch_artist=True)

for ax in axes:
    ax.set_xlabel('')

# We want to make the 4th box in the second axes red    
axes[1].findobj(matplotlib.patches.Patch)[3].set_facecolor("red")

fig = axes[0].get_figure()
fig.suptitle('New title here')
plt.show()

enter image description here