Пошаговая сюжетная линия в matplotlib - PullRequest
1 голос
/ 11 марта 2020

Мне бы хотелось иметь пошаговый линейный сюжет в Matplotlib. Форма линии должна быть похожа на эту (см. Скриншот): Desired shape

Это мой текущий код:

import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline


prices = [12.05, 17.69, 15.31, 12.75, 17.18, 25.05, 33.19, 38.56, 42.9, 38.29, 37.06, 38.94, 36.36, 39.45, 43.97, 46.14, 50.96, 51.04, 48.85, 45.6, 42.38, 39.83, 33.53, 30.03, 28.69
]


price_data = pd.DataFrame(prices, index=range(0, 25))
fig = plt.figure(linewidth=1, figsize=(7, 5))
ax = price_data.plot.line(ax=plt.gca(), color="green"  )
ax.set_facecolor("white")
ax.set_xlabel("Time of day", fontsize = 14, labelpad=8)
ax.set_ylabel("Price in €/MWh", fontsize = 14,labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(0, 60)


plt.xticks(price_data.index, labels=[f'{h:02d}:00' for h in price_data.index], rotation=90)
plt.grid(axis='y', alpha=.4)
plt.tight_layout()
xticks = ['00:00', '01:00', '02:00' , '03:00', '04:00' , '05:00' , '06:00' , '07:00' , '08:00' , 
          '09:00' , '10:00' , '11:00' , '12:00' , '13:00' , '14:00' , '15:00' , '16:00' 
          , '17:00', '18:00', '19:00' , '20:00' , '21:00', '22:00' , '23:00' , '24:00'  ]
xvals = [0, 1*12, 2*12, 3*12, 4*12, 5*12, 6*12, 7*12, 8*12, 9*12, 10*12, 11*12, 12*12, 13*12, 14*12, 15*12, 16*12
        , 17*12, 18*12, 19*12, 20*12, 21*12, 22*12, 23*12, 24*12] 
ax.set(xticks=xvals, xticklabels=xticks)
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='center left', bbox_to_anchor=(0.03, 1.15), fontsize = 14, ncol=3)
plt.savefig('Prices.png', edgecolor='black', dpi=300, bbox_inches='tight')
plt.show()

И это мой токовый выход (см. скриншот): [![

Ответы [ 2 ]

2 голосов
/ 11 марта 2020

Используя замечательные комментарии @ Johan C, вот решение.

Как он сказал, избавьтесь от xticks, xvals, et c. Вы уже правильно определили свои тики с помощью plt.xticks(price_data.index, labels=[f'{h:02d}:00' for h in price_data.index], rotation=90), плюс вам не нужно самостоятельно вводить 24 различных значения.

Чтобы получить пошаговый график, вам просто нужно добавить аргумент drawstyle = "steps-pre" или "steps-post" (или другие параметры, найденные в документации ) для вашей функции построения.

from matplotlib import pyplot as plt
%matplotlib inline

prices = [12.05, 17.69, 15.31, 12.75, 17.18, 25.05, 33.19, 38.56, 42.9, 38.29, 37.06, 38.94, 36.36, 39.45, 43.97, 46.14, 50.96, 51.04, 48.85, 45.6, 42.38, 39.83, 33.53, 30.03, 28.69]    
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=(7, 5))
ax = plt.gca()

ax.plot(hours, prices, color="green", drawstyle="steps-post") # <- drawstyle argument.
ax.set_xlabel("Time of day", fontsize=14, labelpad=8)
ax.set_ylabel("Price in €/MWh", fontsize=14, labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(0, 60)    
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('Prices.png', edgecolor='black', dpi=300, bbox_inches='tight')
plt.show()

enter image description here

1 голос
/ 11 марта 2020

Вам нужно только использовать функцию step на своем графике с такими значениями x и y, как plt.step(xvals, prices) Просто добавьте эту строку после того, как вы определили, что xvals должны дать вам хорошую отправную точку.

Подробнее см. Пример шага :

import pandas as pd
from matplotlib import pyplot as plt

prices = [12.05, 17.69, 15.31, 12.75, 17.18, 25.05, 33.19, 38.56, 42.9, 38.29, 37.06, 38.94, 36.36, 39.45, 43.97, 46.14, 50.96, 51.04, 48.85, 45.6, 42.38, 39.83, 33.53, 30.03, 28.69]

xvals = [0, 1*12, 2*12, 3*12, 4*12, 5*12, 6*12, 7*12, 8*12, 9*12, 10*12, 11*12, 12*12, 13*12, 14*12, 15*12, 16*12, 17*12, 18*12, 19*12, 20*12, 21*12, 22*12, 23*12, 24*12] 

price_data = pd.DataFrame(prices, index=range(0, 25))
fig = plt.figure(linewidth=1, figsize=(7, 5))
ax = price_data.plot.line(ax=plt.gca(), color="green"  )
ax.set_facecolor("white")
ax.set_xlabel("Time of day", fontsize = 14, labelpad=8)
ax.set_ylabel("Price in €/MWh", fontsize = 14,labelpad=8)
ax.set_xlim(0, 288)
ax.set_ylim(0, 60)


plt.xticks(price_data.index, labels=[f'{h:02d}:00' for h in price_data.index], rotation=90)
plt.grid(axis='y', alpha=.4)
plt.tight_layout()
xticks = ['00:00', '01:00', '02:00' , '03:00', '04:00' , '05:00' , '06:00' , '07:00' , '08:00' , 
          '09:00' , '10:00' , '11:00' , '12:00' , '13:00' , '14:00' , '15:00' , '16:00' 
          , '17:00', '18:00', '19:00' , '20:00' , '21:00', '22:00' , '23:00' , '24:00'  ]

plt.step(xvals, prices)
ax.set(xticks=xvals, xticklabels=xticks)
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='center left', bbox_to_anchor=(0.03, 1.15), fontsize = 14, ncol=3)
plt.savefig('Prices.png', edgecolor='black', dpi=300, bbox_inches='tight')
plt.show()

result

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...