以下代码有助于获得带有唯一彩色框的子图。但是所有子图共享一个公共的x和y轴集。我期待每个子图具有独立的轴:
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=(2,2),figsize=(6,4),
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()
答案 0 :(得分:2)
您需要先创建图形和子图,并将其作为参数传递给df.boxplot()
。这也意味着您可以删除参数layout=(2,2)
:
fig, axes = plt.subplots(2,2,sharex=False,sharey=False)
然后使用:
bp_dict = df.boxplot(
by="models", ax=axes, figsize=(6,4),
return_type='both',
patch_artist = True,
)
答案 1 :(得分:1)
您可以将刻度标签设置为再次可见,例如通过
plt.setp(ax.get_xticklabels(), visible=True)
尽管这并不能使轴独立,但它们仍然相互绑定,但似乎您是在询问可见性,而不是这里的共享行为。
答案 2 :(得分:0)
如果您真的认为有必要在创建boxplot
数组后取消共享 轴,则可以执行此操作,但是您必须“手动”完成所有操作。在stackoverflow中搜索了一会儿,并查看了matplotlib
文档页面,我想到了以下解决方案,以取消共享yaxes
实例中的Axes
实例中的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
结果图如下:
说明:
您首先需要告诉每个yaxis
实例,它不应该与任何其他Axis
实例共享其Axes.get_shared_y_axes()
。 This post使我了解如何进行操作-Axes
返回一个Grouper object,其中包含对当前{{1}的所有其他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在我看来是更好的方法。