python - 如何为拆分的 y 轴制作 ax.twinx()?

标签 python matplotlib seaborn subplot

我有以下带有拆分 y 轴的图:

df = pd.DataFrame({
          'x': ["a","b","c","d"], 
          'y': [10,20,30,400],
          'z':[50, 60, 70, 80]})

f, (ax_top, ax_bottom) = plt.subplots(ncols=1, nrows=2, sharex=True, gridspec_kw={'hspace':0.2})

sns.barplot(x='x', y='y', data = df, palette='summer', ax=ax_top)
ax_top.tick_params(top=False, bottom=False, left=False, right=False, labelleft=True,labelbottom=False)

sns.barplot(x='x', y='y', data = df, palette='summer', ax=ax_bottom)

ax_top.set_ylim(bottom=300) 
ax_bottom.set_ylim(0,50)
ax_top.set_xlabel(""), ax_bottom.set_ylabel(""), ax_top.set_ylabel(""), ax_bottom.set_xlabel("")

sns.despine(ax=ax_bottom)
sns.despine(ax=ax_top, bottom=True)

ax = ax_top
d = .015  
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs)     
ax2 = ax_bottom
kwargs.update(transform=ax2.transAxes)  
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs)  

ax3 = ax_top.twinx()
sns.lineplot(x = 'x', y = 'z', data = df, c='red', ax=ax3)
sns.despine()
plt.show()

这会产生以下图像:

enter image description here

有没有办法将绘制 z 的双轴延伸到底部轴 x 轴?我一直在尝试使用 ax_top 和 ax_bottom 的 bbox 添加额外的斧头,但没有运气...... 请注意,理想情况下,该行不会在 ax_topax_bottom 之间断开。

欢迎使用其他拆分 y 轴的解决方案。

非常感谢!

编辑

为什么@jylls 的回答不适用于线图:

代码:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

df = pd.DataFrame({
      'x': ["a","b","c","d"], 
      'y': [10,20,30,400],
      'z':[50, 60, 70, 80]})

f, (ax_top, ax_bottom) = plt.subplots(ncols=1, nrows=2, sharex=True, gridspec_kw={'hspace':0.2})

#Creating top plot
sns.barplot(x='x', y='y', data = df, palette='summer', ax=ax_top)

ax_top.tick_params(top=False, bottom=False, left=False, right=False, 
labelleft=True,labelbottom=False)
ax_top.set_ylim(bottom=300)
ax_top.set_xlabel(""), ax_bottom.set_ylabel(""), ax_top.set_ylabel(""), 
ax_bottom.set_xlabel("")
sns.despine(ax = ax_top)
ax_top.spines['bottom'].set_visible(False)

sns.barplot(x='x', y='y', data = df, palette='summer', ax=ax_bottom)

ax_bottom.set_ylim(0,50)
sns.despine(ax=ax_bottom)

ax = ax_top
d = .015  
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs)        # top-left diagonal

ax2 = ax_bottom
kwargs.update(transform=ax2.transAxes)  
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs)  # bottom-left diagonal
sns.despine(ax = ax2)



#Creating top twin axis
ax_top_2= ax_top.twinx()
sns.lineplot(x='x', y='z', data = df, color='red', ax=ax_top_2)

#Setting z-limits
ax_top_2.set_ylim(60,100)
sns.despine(ax = ax_top_2)
ax_top_2.spines['bottom'].set_visible(False)

#Creating bottom twin axis
ax_bottom_2 = ax_bottom.twinx()
sns.lineplot(x='x', y='z', data = df, color='red', ax=ax_bottom_2)
ax_bottom_2.set_ylim(0,55)
ax_bottom_2.set_ylabel('')

sns.despine(ax=ax_bottom_2)

产生如下图:

enter image description here

是否有可能以某种方式连接那条线? 这就是为什么我认为在 plt 图上放一把斧头会更好……这就是我被困的地方

编辑2 所需的输出在下面以橙色给出:

enter image description here

最佳答案

您的图形由两个轴(ax_topax_bottom)组成。您为顶部图创建了一个双轴(在我的代码中为 ax_top_2)以绘制您的 stripplot,这意味着您需要为底部图创建一个双轴,如果您希望 z 轴延伸到底部 x 轴的底部。一旦创建了双轴 (ax_bottom_2),您将需要考虑要为 z 轴设置的限制。您是否希望所有 z 值都绘制在顶部子图中或底部子图中或两者中?下面,我选择将 stripplot 分布在两个子图中(bottom 和 tot),但根据您要显示的内容,有许多不同的方法可以做到这一点。

您可以在下面的代码中查看更多详细信息:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

df = pd.DataFrame({
          'x': ["a","b","c","d"], 
          'y': [10,20,30,400],
          'z':[50, 60, 70, 80]})

f, (ax_top, ax_bottom) = plt.subplots(ncols=1, nrows=2, sharex=True, gridspec_kw={'hspace':0.2})

#Creating top plot
sns.barplot(x='x', y='y', data = df, palette='summer', ax=ax_top)
ax_top.tick_params(top=False, bottom=False, left=False, right=False, labelleft=True,labelbottom=False)
ax_top.set_ylim(bottom=300) 
ax_top.set_xlabel("")
ax_top.set_ylabel("")

#Creating bottom plot
sns.barplot(x='x', y='y', data = df, palette='summer', ax=ax_bottom)
ax_bottom.set_ylim(0,50)
ax_bottom.set_ylabel("")
ax_bottom.set_xlabel("")


sns.despine(ax=ax_top,bottom=True)
sns.despine(ax=ax_bottom)

d = .015  
kwargs = dict(transform=ax_top.transAxes, color='k', clip_on=False)
ax_top.plot((-d, +d), (-d, +d), **kwargs) 
kwargs.update(transform=ax_bottom.transAxes)  
ax_bottom.plot((-d, +d), (1 - d, 1 + d), **kwargs)  

#Creating top twin axis
ax_top_2= ax_top.twinx()
sns.stripplot(x = 'x', y = 'z', data = df, c='red', ax=ax_top_2)
#Setting z-limits
ax_top_2.set_ylim(55,110)
sns.despine()

#Creating bottom twin axis
ax_bottom_2 = ax_bottom.twinx()
sns.stripplot(x = 'x', y = 'z', data = df, c='red', ax=ax_bottom_2)

#Setting z-limits
ax_bottom_2.set_ylim(0,55)
ax_bottom_2.set_ylabel('')
sns.despine()
plt.show()

输出给出:

enter image description here

关于python - 如何为拆分的 y 轴制作 ax.twinx()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70739980/

相关文章:

python - 如何在谷歌应用引擎(python)中创建一个excel文件?

python - 计算字符串中的小写字符

python - 在 matplotlib 中自动定位文本框

python - 如何在单个 catplot 图中绘制多个数据帧

python - 使用 python 查找低功耗蓝牙

python - mplot3d - 如何显示小刻度?

python - subplot2grid 内有 2 个图

python - 将 seaborn 热图导出为完整的 pgf

matplotlib - Seaborn 散点图矩阵 - 使用自定义样式添加额外的点

python - Python 中的 __rlshift__、__ror__