这是参考以下问题,其中讨论了用于调整子图的标题和布局的选项: modify pandas boxplot output
我的要求是更改每个子图中各个框的颜色(如下图所示):
以下是共享链接上可用的代码,用于调整子图的标题和轴属性:
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实施。谢谢
答案 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()
结果图如下:
希望这会有所帮助。
答案 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()