具有多个子地块和多个y轴的Seaborn地块

2024-06-09 06:26:56 发布

您现在位置:Python中文网/ 问答频道 /正文

使用twinx打印时,如何使用多个子地块

%pylab inline
import pandas as pd
import seaborn as sns; sns.set()

df = pd.DataFrame({'dt':['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'], 'category':['a', 'b', 'a', 'b'], 'foo':[10, 15, 8, 13], 'bar':[12, 8, 5, 18]})
df['dt'] = pd.to_datetime(df['dt'])

ax = sns.lineplot(x='dt', y='foo', data=df, hue='category')
ax.set_ylabel('asdf', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
plt.legend(fontsize='x-large')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
plt.xticks(rotation=90, horizontalalignment='center', fontsize=28)
plt.xlabel('')
plt.yticks(fontsize=16)

ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=df, ax=ax2, color='green')
plt.yticks(fontsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)

plt.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle='--', lw=4)
plt.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar  ', fontsize=28, horizontalalignment='left')
plt.show()


d2 = pd.DataFrame({'dt':['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'], 'category':['a', 'b', 'a', 'b'],'foo':[11, 16, 8, 14], 'bar':[11, 7, 4, 17]})
d2['dt'] = pd.to_datetime(d2['dt'])

ax = sns.lineplot(x='dt', y='foo', data=d2, hue='category')
ax.set_ylabel('something else', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
plt.legend(fontsize='x-large')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
plt.xticks(rotation=90, horizontalalignment='center', fontsize=28)
plt.xlabel('')
plt.yticks(fontsize=16)
plt.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle='--', lw=4)
plt.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar  ', fontsize=28, horizontalalignment='left')


ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=d2, ax=ax2, color='green')
plt.yticks(fontsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)
plt.show()

这或多或少是好的。但是,当添加子图以将多个测量值合并到一个共享x轴的图形中(即节省空间并反复写入日期)时,以下操作失败,并完全扭曲了绘图

ax0 = plt.subplot(211)
ax2 = ax0.twinx()
ax3 = plt.subplot(212)
ax4 = ax3.twinx()

ax = sns.lineplot(x='dt', y='foo', data=df, hue='category', ax=ax0)
ax.set_ylabel('asdf', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
plt.legend(fontsize='x-large')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
plt.xticks(rotation=90, horizontalalignment='center', fontsize=28)
plt.xlabel('')
plt.yticks(fontsize=16)
plt.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle='--', lw=4)
plt.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar  ', fontsize=28, horizontalalignment='left')


#ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=df, ax=ax2, color='green')
plt.yticks(fontsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)
plt.show()


# TODO second plot is missing

Tags: dflabelsfooplotdtbarpltax
1条回答
网友
1楼 · 发布于 2024-06-09 06:26:56

尝试混合the object-oriented syntax and the pyplot接口时总是会出现问题

pyplot functionsplt.XXX)仅影响当前轴(通常是最新创建的,在您的例子中是ax4)。当您有多个轴时,通常最好使用OO函数,这样就不会对正在处理的轴产生歧义

此外,您可能希望通过代码末尾的^{}自动调整轴的位置,以便为标签提供足够的空间

plt.figure()
ax0 = plt.subplot(211)
ax2 = ax0.twinx()
ax3 = plt.subplot(212)
ax4 = ax3.twinx()

ax = sns.lineplot(x='dt', y='foo', data=df, hue='category', ax=ax0)
ax.set_ylabel('asdf', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
ax.set_xticklabels(ax.get_xticklabels(), rotation=90, horizontalalignment='center', fontsize=28)
ax.set_xlabel('')
ax.tick_params(axis='y', labelsize=16)
ax.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle=' ', lw=4)
ax.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar  ', fontsize=28, horizontalalignment='left')


#ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=df, ax=ax2, color='green')
ax2.tick_params(axis='y', labelsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)

plt.tight_layout()
plt.show()

enter image description here

相关问题 更多 >