如何使用带 twinx 的循环绘制两个不同的 y 轴?

How do you plot two different y-axes using a loop with twinx?

我有一个 pandas 数据框,region,包含英国地区的公寓 (Flat) 和独立房产 (Detached) 的价格时间(Month 列)。我正在尝试获取公寓和独立物业的价格随时间变化的图表,以便这些图表有两个不同的 y 轴 - 都是平均价格,但比例不同。

我已经通过使用 twinx() 实现了这一点,但是使用下面的代码我显然得到了两个数字。这些数字中的第一个正是我想要的,但我得到了第二个空白图。我在下面附上了我想要的那种情节的截图。

删除第二个无花果行 fig, ax2 = ... 时,出现错误 NameError: name 'ax2' is not defined。将行 ax2 = ax.twinx() 带出循环也会产生错误 AttributeError: 'numpy.ndarray' object has no attribute 'twinx'。如果没有重复的空白图,我似乎无法弄清楚如何让这个情节发挥作用,非常感谢任何帮助。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

region_list = sorted(region['Area'].unique().tolist())

fig, ax = plt.subplots(nrows=len(region_list), figsize=(13.8,len(region_list)*7))
fig, ax2 = plt.subplots(nrows=len(region_list), figsize=(13.8,len(region_list)*7))

for i in region_list:
    ind = region_list.index(i)
    filt = region['Area'] == i
    ax2[ind] = ax[ind].twinx()
    ax[ind].plot(region.loc[filt]['Month'],region.loc[filt]['Flat'], color='red', marker='o')
    ax[ind].set_ylabel('Average price of flats', color='red', fontsize=14)
    ax2[ind].plot(region.loc[filt]['Month'],region.loc[filt]['Detached'],color='blue',marker='o')
    ax2[ind].set_ylabel('Average price of detached properties',color='blue',fontsize=14)
    ax[ind].set_title(i, size=14)
    ax[ind].xaxis.set_tick_params(labelsize=10)
    ax[ind].yaxis.set_tick_params(labelsize=10)

plt.tight_layout()

为子图创建辅助轴时,结果是一个新对象,不能像子图轴那样使用数组索引进行引用(除非您专门将新的双轴添加到数组中)。

您可能已经看过以下内容:

# with one axis
fig, ax = plt.subplots()
ax2 = ax.twinx()
ax2.plot(...)

但是对于多个子图,同样的逻辑适用:

# with one axis
fig, axes = plt.subplots(1, 2)

ax2 = axes[0].twinx()
ax2.plot(...) # secondary axis on subplot 0

ax2 = axes[1].twinx()
ax2.plot(...) # secondary axis on subplot 1

你的情况:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

region_list = sorted(region['Area'].unique().tolist())

fig, ax = plt.subplots(nrows=len(region_list), figsize=(13.8,len(region_list)*7))

# don't add a second plot - this would be blank
# fig, ax2 = plt.subplots(nrows=len(region_list), figsize=(13.8,len(region_list)*7))

for i in region_list:
    ind = region_list.index(i)
    filt = region['Area'] == i

    # don't index into ax2
    # ax2[ind] = ax[ind].twinx()

    # instead, create a local variable ax2 which is the secondary axis
    # on the subplot ax[ind]
    ax2 = ax[ind].twinx()

    ax[ind].plot(region.loc[filt]['Month'],region.loc[filt]['Flat'], color='red', marker='o')
    ax[ind].set_ylabel('Average price of flats', color='red', fontsize=14)
    ax2.plot(region.loc[filt]['Month'],region.loc[filt]['Detached'],color='blue',marker='o')
    ax2.set_ylabel('Average price of detached properties',color='blue',fontsize=14)
    ax[ind].set_title(i, size=14)
    ax[ind].xaxis.set_tick_params(labelsize=10)
    ax[ind].yaxis.set_tick_params(labelsize=10)

plt.tight_layout()