我想把两个解决方案结合起来。
我有这样的数据:
db = np.array([('Billboard', 1, 520.0, 3),
('Billboard', 2, 520.0, 2),
('Billboard', 3, 612.0, 0),
('Billboard', 4, 410.0, 4),
('Careerbuilder', 1, 410.0, 0),
('Careerbuilder', 2, 820.0, 0),
('Careerbuilder', 3, 410.0, 1),
('Careerbuilder', 4, 820.0, 0),
('Monster.com', 1, 500.0, 3),
('Monster.com', 2, 500.0, 4),
('Monster.com', 3, 450.0, 0),
('Monster.com', 4, 450.0, 7),
('Ads', 1, 120.0, 0),
('Ads', 2, 0.0, 1),
('Ads', 3, 50.0, 1),
('Ads', 4, 100.0, 0),
], dtype=[('Source', 'U20'), ('Month', int), ('Spent', float), ('count', int)])
db = pd.DataFrame(db)
解决方案1:布局很好,但是蓝色的图无法阅读,因为数值与条形图相比太小了。
plt.figure(figsize=(10, 5))
for i, sourse in enumerate(db['Source'].unique()):
plt.subplot(2, 2, i+1)
plt.title(db['Source'].unique()[i])
subdf = db[db['Source'] == sourse][['Month','count', 'Spent']].set_index('Month')
plt.plot(subdf.index, subdf['count'], color='blue')
plt.bar(subdf.index, subdf['Spent'], color='red', alpha=0.5)
plt.show()
解决方案1
解决方案2:添加了另一个y轴的蓝色图正确显示,但布局是垂直的,不是很好。
for i, sourse in enumerate(db['Source'].unique()):
fig, ax = plt.subplots()
plt.title(db['Source'].unique()[i])
subdf = db[db['Source'] == sourse][['Month','count', 'Spent']].set_index('Month')
ax.bar(subdf.index, subdf['Spent'], color='red', alpha=0.5)
ax.set_xlabel("Months",fontsize=14)
ax.set_ylabel("Money spent",color="red",fontsize=14)
ax.set_xticks(list(range(1,5)))
ax2 = ax.twinx()
ax2.plot(subdf.index, subdf['count'], color='blue')
ax2.yaxis.set_major_locator(ticker.MultipleLocator(1.00))
ax2.set_ylabel('People hired', color='blue',fontsize=14)
plt.ylim(0)
plt.show()
解决方案2
所以我有超过20个子图,所以垂直布局不是最好的解决方案。但我想不出一种方法来同时使用这两种解决方案…我能想到的最好的是
m = 0
n = 0
fig, ax = plt.subplots(2, 2, sharex='col', sharey=False, figsize=(10, 5))
for i, sourse in enumerate(db['Source'].unique()):
plt.title(db['Source'].unique()[i])
subdf = db[db['Source'] == sourse][['Month','count', 'Spent']].set_index('Month')
ax[i+m,i+n].bar(subdf.index, subdf['Spent'], color='red', alpha=0.5)
ax.set_xlabel("Months",fontsize=14)
ax.set_ylabel("Money spent",color="red",fontsize=14)
ax2 = ax.twinx()
ax2[i+m,i+n].plot(subdf.index, subdf['count'], color='blue')
ax2.yaxis.set_major_locator(ticker.MultipleLocator(1.00))
ax2.set_ylabel('People hired', color='blue',fontsize=14)
plt.xticks(list(range(1, 13)))
plt.ylim(0)
n += 1
if n == 2:
m += 1
n == 0
plt.show()
但是显示了一个错误
AttributeError Traceback (most recent call last)
<ipython-input-142-aa24c581b7bf> in <module>
8
9 ax[i+m,i+n].bar(subdf.index, subdf['Spent'], color='red', alpha=0.5)
---> 10 ax.set_xlabel("Months",fontsize=14)
11 ax.set_ylabel("Money spent",color="red",fontsize=14)
12
AttributeError: 'numpy.ndarray' object has no attribute 'set_xlabel'
我找到了这个答案AttributeError: 'numpy. 'narray ' object没有属性'plot',但不知道如何在这里应用它!
我稍微修改了你的解决方案#1,并应用了双y轴图。
plt.figure(figsize=(10, 5))
for i, sourse in enumerate(db['Source'].unique()):
plt.subplot(2, 2, i+1)
plt.title(db['Source'].unique()[i])
subdf = db[db['Source'] == sourse][['Month','count', 'Spent']].set_index('Month')
plt.bar(subdf.index, subdf['Spent'], color='red', alpha=0.5)
ax = plt.gca() # get current axis
twin_ax = ax.twinx()
twin_ax.plot(subdf.index, subdf['count'], color='blue')
plt.tight_layout()
plt.show()
我也可以解释你上一个解决方案中的错误。在下一行
fig, ax = plt.subplots(2, 2, sharex='col', sharey=False, figsize=(10, 5))
表示ax
为numpy数组。它的形状是(2, 2)
,它类似于
ax = np.array([
[ax_row_0_col_0, ax_row_0_col1],
[ax_row_1_col_0, ax_row_1_col1],
])
在这种情况下,我们不能做
ax.set_xlabel("Months",fontsize=14)
但是我们必须做一些像
row, col = 0, 0
ax[row, col].set_xlabel("Months",fontsize=14)