Двойная ось Y для нескольких столбцов в Matplotlib - PullRequest
2 голосов
/ 21 февраля 2020

Я хотел бы отобразить следующий фрейм данных в виде диаграммы, но с двойным y axis, я хочу показать area s столбцы с левой стороны и price s столбцы с правой стороны:

             area1      area2        price1      price2
level               
first       263.16      906.58      10443.32     35101.88
second      6879.83    14343.03      2077.79     4415.53
third      31942.75    60864.24       922.87     1774.47

Я попробовал с кодом ниже, он работает, но отображается только левая сторона.

import matplotlib.pyplot as plt

df.plot(kind='bar')
plt.xticks(rotation=45, fontproperties="SimHei")
plt.xlabel("")
plt.legend()

Спасибо.

1 Ответ

1 голос
/ 21 февраля 2020

Если я вас правильно понял, одним из способов может быть это, но вам придется немного «поиграть» со значениями ширины и положения тиков:

import pandas as pd
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(12,5)) 
ax = fig.add_subplot(111) 
ax2 = ax.twinx() 

width = 0.1

df.area1.plot(kind='bar', color='red', ax=ax, width=width, position=0 )
df.area2.plot(kind='bar', color='orange', ax=ax, width=width, position=1)
df.price1.plot(kind='bar', color='blue', ax=ax2, width=width, position=2)
df.price2.plot(kind='bar', color='green', ax=ax2, width=width, position=3)

ax.set_ylabel('Area')
ax2.set_ylabel('Price')
ax.legend(["Area1", "Area2"], bbox_to_anchor=(0.8,1.0))
ax2.legend(["Price1", "Price2"], bbox_to_anchor=(0.9,1.0))
plt.show()

enter image description here

Другой способ заключается в следующем:

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

fig = plt.figure(figsize=(10,5)) 
ax = fig.add_subplot(111) 
ax2 = ax.twinx() 
# ax.set_xticklabels(ax.get_xticklabels(),rotation=45) # Rotation 45 degrees

width = 0.1
ind = np.arange(len(df))

ax.set_ylabel('Area')
ax2.set_ylabel('Price')
ax.set_xlabel('Level')
ax.bar(ind, df.area1, width, color='red', label='area1')
ax.bar(ind + width, df.area2, width, color='orange', label='area2')
ax2.bar(ind + 2*width, df.price1, width, color='blue', label='price1')
ax2.bar(ind + 3*width, df.price2, width, color='green', label='price2')

ax.set(xticks=(ind + 1.5*width), xticklabels=df.index, xlim=[2*width - 1, len(df)])
ax.legend(["Area1", "Area2"], bbox_to_anchor=(1,1))
ax2.legend(["Price1", "Price2"], bbox_to_anchor=(1,0.87))

plt.show()

enter image description here

...