Matplotlib — отображение дат в днях и часах (ось x) по сравнению со значениями (ось y)

#python #pandas #dataframe #date #matplotlib

#python #панды #фрейм данных #Дата #matplotlib

Вопрос:

У меня есть xlsx файл, содержащий два столбца. Первая — это временная метка (DT-Index), подобная этой (18.01.2012 06:00:00), а вторая содержит обычные значения.

У меня есть 1 год временных меток, разделенных на 24 часа в сутки, что составляет в общей сложности 8736 значений. Теперь я хочу отобразить эти данные, как показано на следующем рисунке.введите описание изображения здесь

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


test = ['Monday - 00', 'Monday - 01', 'Monday - 02',
            'Monday - 03', 'Monday - 04', 'Monday - 05', 'Monday - 06', 'Monday - 07', 'Monday - 08', 'Monday - 09', 'Monday - 10',
             'Monday - 11', 'Monday - 12', 'Monday - 13', 'Monday - 14', 'Monday - 15', 'Monday - 16', 'Monday - 17', 'Monday - 18',
              'Monday - 19', 'Monday - 20', 'Monday - 21', 'Monday - 22', 'Monday - 23' ,'Tuesday - 00', 'Tuesday - 01', 'Tuesday - 02', 'Tuesday - 03', 'Tuesday - 04', 'Tuesday - 05', 'Tuesday - 06', 'Tuesday - 07', 
'Tuesday - 08', 'Tuesday - 09', 'Tuesday - 10', 'Tuesday - 11', 'Tuesday - 12', 'Tuesday - 13', 'Tuesday - 14'
, 'Tuesday - 15', 'Tuesday - 16', 'Tuesday - 17', 'Tuesday - 18', 'Tuesday - 19', 'Tuesday - 20', 'Tuesday - 21',
'Tuesday - 22', 'Tuesday - 23', 
'Wednesday - 00', 'Wednesday - 01', 'Wednesday - 02', 'Wednesday - 03', 'Wednesday - 04', 'Wednesday - 05', 'Wednesday - 06', 'Wednesday - 07',
'Wednesday - 08', 'Wednesday - 09', 'Wednesday - 10', 'Wednesday - 11', 'Wednesday - 12', 'Wednesday - 13', 'Wednesday - 14', 'Wednesday - 15',
 'Wednesday - 16', 'Wednesday - 17', 'Wednesday - 18', 'Wednesday - 19', 'Wednesday - 20', 'Wednesday - 21', 'Wednesday - 22', 'Wednesday - 23',
  'Thursday - 00', 'Thursday - 01', 'Thursday - 02', 'Thursday - 03', 'Thursday - 04', 'Thursday - 05', 'Thursday - 06', 'Thursday - 07'
  , 'Thursday - 08', 'Thursday - 09', 'Thursday - 10', 'Thursday - 11', 'Thursday - 12', 'Thursday - 13', 'Thursday - 14', 'Thursday - 15',
   'Thursday - 16', 'Thursday - 17', 'Thursday - 18', 'Thursday - 19', 'Thursday - 20', 'Thursday - 21', 'Thursday - 22', 'Thursday - 23',
    'Friday - 00', 'Friday - 01', 'Friday - 02', 'Friday - 03', 'Friday - 04', 'Friday - 05', 'Friday - 06', 'Friday - 07', 'Friday - 08',
     'Friday - 09', 'Friday - 10', 'Friday - 11', 'Friday - 12', 'Friday - 13', 'Friday - 14', 'Friday - 15', 'Friday - 16', 'Friday - 17',
      'Friday - 18', 'Friday - 19', 'Friday - 20', 'Friday - 21', 'Friday - 22', 'Friday - 23', 'Saturday - 00', 'Saturday - 01', 'Saturday - 02',
       'Saturday - 03', 'Saturday - 04', 'Saturday - 05', 'Saturday - 06', 'Saturday - 07', 'Saturday - 08', 'Saturday - 09', 'Saturday - 10', 
       'Saturday - 11', 'Saturday - 12', 'Saturday - 13', 'Saturday - 14', 'Saturday - 15', 'Saturday - 16', 'Saturday - 17', 'Saturday - 18',
        'Saturday - 19', 'Saturday - 20', 'Saturday - 21', 'Saturday - 22', 'Saturday - 23', 'Sunday - 00', 'Sunday - 01', 'Sunday - 02',
         'Sunday - 03', 'Sunday - 04', 'Sunday - 05', 'Sunday - 06', 'Sunday - 07', 'Sunday - 08', 'Sunday - 09', 'Sunday - 10',
          'Sunday - 11', 'Sunday - 12', 'Sunday - 13', 'Sunday - 14', 'Sunday - 15', 'Sunday - 16', 'Sunday - 17', 'Sunday - 18',
           'Sunday - 19', 'Sunday - 20', 'Sunday - 21', 'Sunday - 22', 'Sunday - 23',];




df = pd.read_excel('file.xlsx' , sheet_name="x")
blue = df.loc[df['DT-Index'].map(lambda date: date.month == 12 or date.month == 1 or date.month == 2)]
red = df.loc[df['DT-Index'].map(lambda date: date.month == 3 or date.month == 4 or date.month == 10 or date.month == 11)]
purple = df.loc[df['DT-Index'].map(lambda date: date.month == 5 or date.month == 9)]
green = df.loc[df['DT-Index'].map(lambda date: date.month == 6 or date.month == 7 or date.month == 8)]

xB =  list(blue['DT-Index'])
yB = list(blue['values'])

xR =  list(red['DT-Index'])
yR = list(red['values'])

xP =  list(purple['DT-Index'])
yP = list(purple['values'])

xG =  list(green['DT-Index'])
yG = list(green['values'])

def mittelwerte(dic):
  for val in dic.keys():
      dic[val] = int(sum(dic[val]) / len(dic[val]))
  return dic;

def appendToDict(x , y):
  data = dict()
  xAF = list(map(lambda date: date.to_pydatetime() , x))
  for i in range(len(x)):
      day = xAF[i].strftime("%A - %H")
      if day in data.keys():
          data[day].append(y[i])
      
      else :
          data[day] = [y[i]]
  return sortDict(mittelwerte(data) , test)

def sortDict(dic , keys):
  data = dict.fromkeys(keys);
  for data1 in data.keys():
      for data2 in dic.keys():
          if(data1 == data2):
              data[data1] = dic[data2]
  return data;




dataB = appendToDict(xB , yB)
dataR = appendToDict(xR , yR)
dataP = appendToDict(xP , yP)
dataG = appendToDict(xG , yG)

# my_xticks = ['Monday','Tuesday','Wednesday','Thursday','Friday' , 'Saturday' , 'Sunday']
# plt.xticks(list(dataB.keys()), my_xticks)

plt.plot(list(dataB.keys()), list(dataB.values()), color='#3074bb')
plt.plot(list(dataR.keys()), list(dataR.values()), color='#bb3530')
plt.plot(list(dataP.keys()), list(dataP.values()), color='#a630bb')
plt.plot(list(dataG.keys()), list(dataG.values()), color='#30bb40')

plt.ylabel('Y Values')
plt.legend()
plt.show()


  

Проблема, с которой я сталкиваюсь, заключается в том, что дней много, и когда я пытаюсь построить их таким образом, я получаю понедельник 20 раз и больше. Как я могу достичь решения, показанного на рисунке?

—————Обновления—————

Я попытался найти решение на первом рисунке, но у меня возникла проблема по оси x, как показано на следующем рисунке, он отображает весь список, что я должен сделать, чтобы достичь желаемого результата на первом рисунке matplotlib

Ответ №1:

 my_xticks1 = ['Montag','Dienstag','Mittwoch','Donnerstag','Freitag' , 'Samstag' , 'Sonntag' , 'aa']
my_major_xticks = ['00' , '00','00','00','00','00' , '00' , '00']
my_minor_xticks = [0 , 5 , 11 , 17 , 23 , 29 , 35 , 41 , 47 , 53 , 59 , 65 , 71 , 77 , 83 , 89 , 95 , 101 , 107 , 113 , 119 , 125 , 131 , 137 , 143 , 149 , 155 , 161 , 167]
my_minor_label = ['06' , '12' , '18' , '06' , '12' , '18' , '06' , '12' , '18' ,'06' , '12' , '18', '06' , '12' , '18' , '06' , '12' , '18' , '06' , '12' , '18']


fig, ax = plt.subplots()

ax.plot(list(dataB.keys()), list(dataB.values()), label="Dec-Feb" , color='#3074bb')
ax.plot(list(dataR.keys()), list(dataR.values()), label="Mar-Apr amp; Oct-Nov" , color='#bb3530')
ax.plot(list(dataP.keys()), list(dataP.values()), label="Dec-Feb" , color='#a630bb')
ax.plot(list(dataG.keys()), list(dataG.values()), label="Jun-Aug" , color='#30bb40')
ax.set_ylim(ymin=0)
ax.set_xlim(xmin=0)
ax.set_ylabel('Wärmelast / kW')
ax.set_title("Test")



#set the major xticks by its location and the location is presented by the length of the list
plt.xticks([0,23,47,71,95,119,143,167] , my_major_xticks)
# both for x and y axis

ax.tick_params('both', length=7, width=1, which='major')
plt.grid()

# control the minor locator and added a fixedlocator function to it
ax.xaxis.set_minor_locator(FixedLocator(my_minor_xticks))
# add the label to the minor locator
ax.xaxis.set_minor_formatter(FixedFormatter(my_minor_label))

ax.legend()

num = 11
for i, xpos in enumerate(ax.get_xticks()):
    if(i == 7):
        break;
    ax.text(num,-40, my_xticks1[i], 
            size = 10, ha = 'center')
    num = num   24
  

я просто решил это с помощью xticks , set_minor_locator и ax.text
я только что опубликовал приведенный выше код