неправильное выравнивание по оси x в mathplotlib на гистограмме и линейном графике

#python #numpy #matplotlib #plot

Вопрос:

Я заметил, что когда вы строите линейчатую и столбчатую диаграммы, они имеют разное выравнивание по оси x, несмотря на то, что у них один и тот же источник данных для оси x. Кто-нибудь может помочь мне сделать ось 1,2,3 на диаграммах похожей на 4-ю? (внизу). Я никогда не работал ни с python, ни с библиотекой mathplot, и я довольно растерян и понятия не имею, почему гистограмма отличается с точки зрения визуализации по оси x. Спасибо за любую подсказку/помощь. (json был обрезан)

[ubuntu 18.4, jetson nano, python3, возможно, последняя версия mathplotlib (3.4.что-то)]

введите описание изображения здесь

 import json
import glob
from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np

a = []
dates = []
temp_min = []
temp_max = []
wind_deg = []
rain = []
clouds = []


with open(datetime.today().strftime('%Y-%m-%d')   '.json') as f:
  try:
    data = json.load(f)
    for hour in data["hourly"]:
      print(datetime.utcfromtimestamp(hour["dt"]).strftime('%Y-%m-%d %H:%M:%S'))
      dates.append(datetime.utcfromtimestamp(hour.get("dt")).strftime('%Y-%m-%d %H:%M:%S'))
      a.append(hour.get('temp'))
      wind_deg.append(hour.get('wind_deg'))
      r = hour.get('rain', { '1h': 0})
      rain.append(r['1h'])
      clouds.append(hour.get('clouds', 0))
  except:
    print(f)

temp = np.array(a)
wind_deg = np.array(wind_deg)
rain = np.array(rain)
clouds = np.array(clouds)


x = [datetime.strptime(d,'%Y-%m-%d %H:%M:%S') for d in dates]
print(x)
y = range(len(x)) # many thanks to Kyss Tao for setting me straight here

plt.figure(figsize=(15, 15), dpi=90)
# plt.figure()

plt.subplot(411)
plt.tick_params(axis='y', which='major')
plt.tick_params(axis='y', which='minor')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.gca().xaxis.set_minor_formatter(mdates.DateFormatter('%H'))
plt.gca().xaxis.set_minor_locator(mdates.HourLocator(byhour=range(0,24,2)))
plt.plot(x, temp, 'k')
plt.gcf().autofmt_xdate()
plt.grid(True)


plt.subplot(412)
plt.tick_params(axis='y', which='major')
plt.tick_params(axis='y', which='minor')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.gca().xaxis.set_minor_formatter(mdates.DateFormatter('%H'))
plt.gca().xaxis.set_minor_locator(mdates.HourLocator(byhour=range(0,24,2)))
plt.axis([None, None,0,360])
plt.plot(x, wind_deg, 'bo')
plt.gcf().autofmt_xdate()
plt.grid(True)


plt.subplot(413)
plt.tick_params(axis='y', which='major')
plt.tick_params(axis='y', which='minor')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.gca().xaxis.set_minor_formatter(mdates.DateFormatter('%H'))
plt.gca().xaxis.set_minor_locator(mdates.HourLocator(byhour=range(0,24,2)))
plt.plot(x, rain, 'b') 
plt.gcf().autofmt_xdate()
plt.grid(True)


plt.subplot(414)
plt.tick_params(axis='y', which='major')
plt.tick_params(axis='y', which='minor')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.gca().xaxis.set_minor_formatter(mdates.DateFormatter('%H'))
plt.gca().xaxis.set_minor_locator(mdates.HourLocator(byhour=range(0,24,2)))
plt.bar(x, clouds, color='b') # temp_min, temp_max)
plt.gcf().autofmt_xdate()

plt.grid(True)


plt.savefig('day.png')
 

входные данные:

 {
  "lat": 48.1482,
  "lon": 17.1067,
  "timezone": "Europe/Bratislava",
  "timezone_offset": 7200,
  "current": {
    "dt": 1624337955,
    "sunrise": 1624330291,
    "sunset": 1624388134,
    "temp": 21.58,
    "feels_like": 21.91,
    "pressure": 1008,
    "humidity": 81,
    "dew_point": 18.18,
    "uvi": 0.67,
    "clouds": 0,
    "visibility": 10000,
    "wind_speed": 3.09,
    "wind_deg": 330,
    "weather": [
      {
        "id": 800,
        "main": "Clear",
        "description": "jasná obloha",
        "icon": "01d"
      }
    ]
  },
  "hourly": [
    {
      "dt": 1624334400,
      "temp": 20.96,
      "feels_like": 21.3,
      "pressure": 1008,
      "humidity": 84,
      "dew_point": 18.15,
      "uvi": 0.2,
      "clouds": 0,
      "visibility": 10000,
      "wind_speed": 1.24,
      "wind_deg": 45,
      "wind_gust": 1.89,
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "jasná obloha",
          "icon": "01d"
        }
      ],
      "pop": 0.06
    },
    {
      "dt": 1624338000,
      "temp": 21.58,
      "feels_like": 21.91,
      "pressure": 1008,
      "humidity": 81,
      "dew_point": 18.18,
      "uvi": 0.67,
      "clouds": 0,
      "visibility": 10000,
      "wind_speed": 2.45,
      "wind_deg": 316,
      "wind_gust": 3.77,
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "jasná obloha",
          "icon": "01d"
        }
      ],
      "pop": 0.08
    },
    {
      "dt": 1624341600,
      "temp": 21.69,
      "feels_like": 22,
      "pressure": 1008,
      "humidity": 80,
      "dew_point": 18.09,
      "uvi": 1.61,
      "clouds": 0,
      "visibility": 10000,
      "wind_speed": 3.83,
      "wind_deg": 314,
      "wind_gust": 5.39,
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "jasná obloha",
          "icon": "01d"
        }
      ],
      "pop": 0.08
    },
    {
      "dt": 1624345200,
      "temp": 22.37,
      "feels_like": 22.67,
      "pressure": 1008,
      "humidity": 77,
      "dew_point": 18.14,
      "uvi": 3.11,
      "clouds": 4,
      "visibility": 10000,
      "wind_speed": 4.62,
      "wind_deg": 322,
      "wind_gust": 5.69,
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "jasná obloha",
          "icon": "01d"
        }
      ],
      "pop": 0
    },
      ],
      "pop": 0.18
    }
  ]
}
 

Ответ №1:

Я верю, что установка значения sharex в True решит вашу проблему. Ниже приведен мой объектно-ориентированный способ создания фигуры с четырьмя участками, расположенными на одной оси x. Я не мог загрузить ваши данные, поэтому я создал случайные массивы, чтобы показать свое решение.

 import datetime as dt

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

x = [dt.datetime(2021, 6, 23, i) for i in range(24)]

temp = np.random.normal(size=len(x))
wind_deg = np.random.normal(size=len(x))
rain = np.random.normal(size=len(x))
clouds = np.abs(np.random.normal(size=len(x)))

fig, graphs = plt.subplots(4, 1, sharex=True)

graphs[0].plot(x, temp, 'k')
graphs[1].plot(x, wind_deg, 'bo')
graphs[2].plot(x, rain, 'b')
graphs[3].bar(x, clouds, color='b')


# with the shared axis, only apply formatting to the bottom graph
graphs[-1].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
graphs[-1].xaxis.set_major_locator(mdates.DayLocator())
graphs[-1].xaxis.set_minor_formatter(mdates.DateFormatter('%H'))
graphs[-1].xaxis.set_minor_locator(mdates.HourLocator(byhour=range(0,24,2)))
fig.autofmt_xdate()

fig.savefig('day.png')