簡體   English   中英

Seaborn plot 具有多個子圖和每個子圖的多個 y 軸

[英]Seaborn plot with multiple subplots and multiple y axis for each one

使用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 軸的圖形(即節省空間並一遍又一遍地寫入日期)時,以下內容無法正常工作並完全扭曲了 plot

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

嘗試混合面向對象的語法和 pyplot接口時總是會出現問題。

pyplot 函數plt.XXX )僅影響當前軸(通常是最新創建的,在您的情況下ax4 )。 當您有多個軸時,通常最好使用 OO 函數,這樣您正在處理的軸就不會產生歧義。

此外,您可能希望通過代碼末尾的tight_layout()自動調整軸的 position 以為標簽留出足夠的空間

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()

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM