如果您真的认为有必要在创建boxplot 数组之后取消共享轴,您可以这样做,但您必须“手动”完成所有操作。通过stackoverflow搜索一段时间并查看matplotlib文档页面,我想出了以下解决方案来取消共享Axes实例的yaxes,对于xaxes,您必须进行类似的操作:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.ticker import AutoLocator, AutoMinorLocator
##using differently scaled data for the different random series:
df = pd.DataFrame(
np.asarray([
np.random.rand(140),
2*np.random.rand(140),
4*np.random.rand(140),
8*np.random.rand(140),
]).T,
columns=['A', 'B', 'C', 'D']
)
df['models'] = pd.Series(np.repeat([
'model1','model2', 'model3', 'model4', 'model5', 'model6', 'model7'
], 20))
##creating the boxplot array:
bp_dict = df.boxplot(
by="models",layout = (2,2),figsize=(6,8),
return_type='both',
patch_artist = True,
rot = 45,
)
colors = ['b', 'y', 'm', 'c', 'g', 'b', 'r', 'k', ]
##adjusting the Axes instances to your needs
for row_key, (ax,row) in bp_dict.items():
ax.set_xlabel('')
##removing shared axes:
grouper = ax.get_shared_y_axes()
shared_ys = [a for a in grouper]
for ax_list in shared_ys:
for ax2 in ax_list:
grouper.remove(ax2)
##setting limits:
ax.axis('auto')
ax.relim() #<-- maybe not necessary
##adjusting tick positions:
ax.yaxis.set_major_locator(AutoLocator())
ax.yaxis.set_minor_locator(AutoMinorLocator())
##making tick labels visible:
plt.setp(ax.get_yticklabels(), visible=True)
for i,box in enumerate(row['boxes']):
box.set_facecolor(colors[i])
plt.show()
生成的图如下所示:
解释:
您首先需要告诉每个Axes 实例它不应与任何其他Axis 实例共享其yaxis。 This post 让我了解了如何做到这一点——Axes.get_shared_y_axes() 返回一个Grouper object,它包含对所有其他Axes 实例的引用,当前Axes 应该与之共享其xaxis。循环遍历这些实例并调用 Grouper.remove 会执行实际的取消共享。
yaxis 取消共享后,y 限制和 y 刻度需要调整。前者可以通过ax.axis('auto') 和ax.relim() 实现(不确定是否需要第二条命令)。可以使用ax.yaxis.set_major_locator() 和ax.yaxis.set_minor_locator() 以及适当的Locators 来调整刻度。最后,可以使用plt.setp(ax.get_yticklabels(), visible=True) (see here) 使刻度标签可见。
考虑到这一切,我认为@DavidG 的answer 是更好的方法。