Собираем два участка с разными осями в один с Matplotlib - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть два участка в Matplotlib, которые я хотел бы объединить. У них разные оси и масштабы. Вот код для каждого из них. График электропитания:

    #Case Study: Curtailment
from matplotlib import pyplot as plt
%matplotlib inline

load = [0, 250, 250, 250, 250, 250, 665, 2500, 2500, 2500, 2500, 2500,0,2500, 2366, 250, 250, 373, 2500,0, 2500, 0, 2500,250, 0]    
hours = list(range(25)) # [0, 1, 2, ... 22, 23, 24]
labels = [f'{h:02d}:00' for h in hours] # ["00:00", "01:00", ... "23:00", "24:00"]

fig = plt.figure(linewidth=1, figsize=(9, 5))
ax = plt.gca()


ax.plot(hours, load, color="goldenrod",drawstyle="steps-post",  linewidth=3) # <- drawstyle argument.
ax.set_xlabel("Time of day", fontsize=14, labelpad=8)
ax.set_ylabel("Electrical power in W", fontsize=14, labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(0, 3000)    
plt.xticks(hours, labels=labels, rotation=90)
plt.grid(axis='y', alpha=.4)
ax.tick_params(axis='both', which='major', labelsize=14)
# (Optional) ax.legend(loc='center left', bbox_to_anchor=(0.03, 1.15), fontsize = 14, ncol=3)
plt.tight_layout() # This must be called last, after all elements (plot and legend) are ready.
plt.savefig('CS_Curtailment_ElectricalLoad.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()

График температуры:

#Case Study: Curtailment
from matplotlib import pyplot as plt
%matplotlib inline

temperature = [
21.00,
21.02,
20.96,
20.85,
20.68,
20.46,
20.40,
20.56,
20.77,
21.06,
21.41,
21.79,
21.10,
21.57,
22.00,
21.47,
20.92,
20.46,
20.92,
20.31,
20.77,
20.35,
20.90,
21.00,
21.00
]    
hours = list(range(25)) # [0, 1, 2, ... 22, 23, 24]
labels = [f'{h:02d}:00' for h in hours] # ["00:00", "01:00", ... "23:00", "24:00"]

fig = plt.figure(linewidth=1, figsize=(9, 5))
ax = plt.gca()


ax.plot(hours, temperature, color="red",  linewidth=3) # <- drawstyle argument.
ax.set_xlabel("Time of day", fontsize=14, labelpad=8)
ax.set_ylabel("Temperature in °C", fontsize=14, labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(20, 22.5)    
plt.xticks(hours, labels=labels, rotation=90)
plt.grid(axis='y', alpha=.4)
ax.tick_params(axis='both', which='major', labelsize=14)
# (Optional) ax.legend(loc='center left', bbox_to_anchor=(0.03, 1.15), fontsize = 14, ncol=3)
plt.tight_layout() # This must be called last, after all elements (plot and legend) are ready.
plt.savefig('CS_Curtailment_Temperature.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()

Я бы хотел, чтобы ось электропитания была слева (первый график), а ось температуры справа (вторая) сюжет). Конечно, два графика имеют одинаковые значения по оси X. Можете ли вы сделать это с Matplotlib?

Буду признателен за каждый комментарий.

1 Ответ

1 голос
/ 06 апреля 2020

Да, это можно сделать в matplotlib, чтобы сначала сгенерировать первую ax (электрическую мощность), а затем создать вторую ось

ax.plot(hours, load, color="goldenrod",drawstyle="steps-post",  linewidth=3)
# ... 

#generate the second instance
ax2 = ax.twinx()
ax2.plot(hours, temperature, color="red",  linewidth=3)
# ... set additional configuration for ax2

Обе оси будут иметь одинаковые x-axes и то же самое fig, поэтому убедитесь, что перед тем, как показать график, чтобы сжать макет, в противном случае y-метка может быть обрезана.

fig.tight_layout()
plt.show()

РЕДАКТИРОВАТЬ:

Чтобы обрабатывать обе оси одновременно, вам нужно использовать объект рисунка, поэтому используйте его, чтобы сохранить их в png и установить легенду. legend() метод должен получить labels, который вы можете установить вручную для каждого ax.plot( ..., label='<label>')

  1. получить текущую цифру до plt.show()
  2. Установить легенду, используя объект рисунка.
  3. Сохраните изображение, используя объект рисунка.
  4. Показ изображения.

Код:

fig = plt.gcf()
fig.legend(loc='center left', bbox_to_anchor=(0.15, 1.07), fontsize=14, ncol=3)
fig.savefig('CS_Curtailment_CombinedDiagram.png',
        edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...