Python - 当同时使用 matplotlib 和 pandas 绘图时,x-axis 使用 pandas 是准确的,但不是 matplotlib
Python - When plotting using both matplotlib and pandas, the x-axis is accurate using pandas, but not matplotlib
(这是我第一个 Whosebug 问题!)
我有一个 pandas 数据框,其中包含一天中 15 分钟间隔的太阳辐照度值。此数据帧的索引是“DatetimeIndex”(dtype='datetime64[ns, America/New_York]',并本地化到其各自的时区。因此,索引值以“1997-01-20 00:15:00-05:00”开始,“ 1997-01-20 00:30:00-05:00" ... "1997-01-21 00:00:00-5:00" (注意最后一个条目是第二天凌晨 12 点)。
单独绘制此数据框(名为 poa_irradiance_swd_corrected
)时,一切看起来都很棒。这是我的代码及其输出的示例:
代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import pvlib as pv
import datetime as dt
import math
import pytz
import time
plt.figure()
poa_irradiance_swd_corrected.plot().get_figure().set_facecolor('white')
输出:
此数据框中最高的“poa_global”辐照度测量值介于 12:00 PM(中午)和 1:30-ish 之间。这是准确的。
我还有另外两个数据帧(名为 poa_irradiance_swd_flat
和 modeled_poa_irradiance_swd
)具有类似的辐照度测量值。为了直观地比较辐照度测量值,我使用 matplotlib 的 subplot 函数将所有 3 个数据帧放入一个图中。 然而,X-axis 的子图非常不准确。代码和输出如下所示:
代码:
fig, axs = plt.subplots(2,2, sharex=True,sharey=True, facecolor='white',figsize=(12,8))
fig.suptitle('Sunny Winter Day',size='xx-large',weight='bold')
axs[0,0].plot(poa_irradiance_swd_flat)
axs[0,0].set_title('POA Irradiance (Flat)')
axs[0,1].plot(modeled_poa_irradiance_swd)
axs[0,1].set_title('Modeled Data (Tilted)')
axs[1,0].plot(poa_irradiance_swd_corrected)
axs[1,0].set_title('POA Irradiance (Tilted)')
axs[1,1].plot(modeled_poa_irradiance_swd)
axs[1,1].set_title('Modeled Data (Tilted)')
for axs in axs.flat:
axs.set(ylabel='Irradiance $W/m^2$')
axs.xaxis.set_major_formatter(DateFormatter('%H:%M'))
plt.tight_layout(pad=0, w_pad=0, h_pad=3)
fig.autofmt_xdate()
输出:
请注意,右边的两个图完全相同。我只是用右边的图与左边的图进行比较
请注意 x-axis 如何在 6 小时后完全关闭。
我有 cross-checked 数据帧本身,而且,最高辐照度时间与 12:00 下午(中午)和大约 1:30-ish 之间的时间重合...... 不是 在 18:00 附近(这是 6:00 下午,没有意义)。我什至在 axs[1,0].plot(poa_irradiance_swd_corrected)
代码行中使用了完全相同的数据框。
如何让X-axis显示准确的时间?
编辑(回应scespinoza):
所以我尝试从数据框中传递相应的 .index
和 .values
值,并成功绘制...但仍然存在相同的问题。
然后,我尝试将 ax
命令传递给 plot 函数本身,如下所示:每个子图的 poa_irradiance_swd_flat.plot(ax=axs[0, 0])
。将 matplotlib 作为 mpl 导入后,我还在代码的顶部添加了 mpl.rcParams['timezone'] = 'UTC'
。
现在,我收到一个 ValueError:
ValueError Traceback (most recent call last)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/IPython/core/formatters.py:339, in BaseFormatter.__call__(self, obj)
337 pass
338 else:
--> 339 return printer(obj)
340 # Finally look for special method names
341 method = get_real_method(obj, self.print_method)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/IPython/core/pylabtools.py:151, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
148 from matplotlib.backend_bases import FigureCanvasBase
149 FigureCanvasBase(fig)
--> 151 fig.canvas.print_figure(bytes_io, **kw)
152 data = bytes_io.getvalue()
153 if fmt == 'svg':
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/backend_bases.py:2295, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2289 renderer = _get_renderer(
2290 self.figure,
2291 functools.partial(
2292 print_method, orientation=orientation)
2293 )
2294 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2295 self.figure.draw(renderer)
2297 if bbox_inches:
2298 if bbox_inches == "tight":
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/artist.py:73, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
71 @wraps(draw)
72 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 73 result = draw(artist, renderer, *args, **kwargs)
74 if renderer._rasterizing:
75 renderer.stop_rasterizing()
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/artist.py:50, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
47 if artist.get_agg_filter() is not None:
48 renderer.start_filter()
---> 50 return draw(artist, renderer)
51 finally:
52 if artist.get_agg_filter() is not None:
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/figure.py:2810, in Figure.draw(self, renderer)
2807 # ValueError can occur when resizing a window.
2809 self.patch.draw(renderer)
-> 2810 mimage._draw_list_compositing_images(
2811 renderer, self, artists, self.suppressComposite)
2813 for sfig in self.subfigs:
2814 sfig.draw(renderer)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
135 image_group = []
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/artist.py:50, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
47 if artist.get_agg_filter() is not None:
48 renderer.start_filter()
---> 50 return draw(artist, renderer)
51 finally:
52 if artist.get_agg_filter() is not None:
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axes/_base.py:3046, in _AxesBase.draw(self, renderer)
3043 for spine in self.spines.values():
3044 artists.remove(spine)
-> 3046 self._update_title_position(renderer)
3048 if not self.axison:
3049 for _axis in self._get_axis_list():
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axes/_base.py:2986, in _AxesBase._update_title_position(self, renderer)
2983 for ax in axs:
2984 if (ax.xaxis.get_ticks_position() in ['top', 'unknown']
2985 or ax.xaxis.get_label_position() == 'top'):
-> 2986 bb = ax.xaxis.get_tightbbox(renderer)
2987 else:
2988 bb = ax.get_window_extent(renderer)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axis.py:1103, in Axis.get_tightbbox(self, renderer, for_layout_only)
1100 if not self.get_visible():
1101 return
-> 1103 ticks_to_draw = self._update_ticks()
1105 self._update_label_position(renderer)
1107 # go back to just this axis's tick labels
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axis.py:1046, in Axis._update_ticks(self)
1041 """
1042 Update ticks (position and labels) using the current data interval of
1043 the axes. Return the list of ticks that will be drawn.
1044 """
1045 major_locs = self.get_majorticklocs()
-> 1046 major_labels = self.major.formatter.format_ticks(major_locs)
1047 major_ticks = self.get_major_ticks(len(major_locs))
1048 self.major.formatter.set_locs(major_locs)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/ticker.py:224, in Formatter.format_ticks(self, values)
222 """Return the tick labels for all the ticks at once."""
223 self.set_locs(values)
--> 224 return [self(value, i) for i, value in enumerate(values)]
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/ticker.py:224, in <listcomp>(.0)
222 """Return the tick labels for all the ticks at once."""
223 self.set_locs(values)
--> 224 return [self(value, i) for i, value in enumerate(values)]
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/dates.py:636, in DateFormatter.__call__(self, x, pos)
635 def __call__(self, x, pos=0):
--> 636 result = num2date(x, self.tz).strftime(self.fmt)
637 return _wrap_in_tex(result) if self._usetex else result
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/dates.py:528, in num2date(x, tz)
526 if tz is None:
527 tz = _get_rc_timezone()
--> 528 return _from_ordinalf_np_vectorized(x, tz).tolist()
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/numpy/lib/function_base.py:2163, in vectorize.__call__(self, *args, **kwargs)
2160 vargs = [args[_i] for _i in inds]
2161 vargs.extend([kwargs[_n] for _n in names])
-> 2163 return self._vectorize_call(func=func, args=vargs)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/numpy/lib/function_base.py:2246, in vectorize._vectorize_call(self, func, args)
2243 # Convert args to object arrays first
2244 inputs = [asanyarray(a, dtype=object) for a in args]
-> 2246 outputs = ufunc(*inputs)
2248 if ufunc.nout == 1:
2249 res = asanyarray(outputs, dtype=otypes[0])
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/dates.py:350, in _from_ordinalf(x, tz)
347 dt = (np.datetime64(get_epoch()) +
348 np.timedelta64(int(np.round(x * MUSECONDS_PER_DAY)), 'us'))
349 if dt < np.datetime64('0001-01-01') or dt >= np.datetime64('10000-01-01'):
--> 350 raise ValueError(f'Date ordinal {x} converts to {dt} (using '
351 f'epoch {get_epoch()}), but Matplotlib dates must be '
352 'between year 0001 and 9999.')
353 # convert from datetime64 to datetime:
354 dt = dt.tolist()
ValueError: Date ordinal 14228655 converts to 40926-09-26T00:00:00.000000 (using epoch 1970-01-01T00:00:00), but Matplotlib dates must be between year 0001 and 9999.
无法真正重现您的问题,但也许您可以尝试将系列的索引和值分别传递给 plot 函数。
...
axs[0,0].plot(poa_irradiance_swd_flat.index, poa_irradiance_swd_flat.values)
...
此外,请注意,您可以将 ax
属性传递给 Series
的 .plot()
函数,因此您可以将代码重构为如下内容:
fig, axs = plt.subplots(2,2, sharex=True,sharey=True, facecolor='white',figsize=(12,8))
fig.suptitle('Sunny Winter Day',size='xx-large',weight='bold')
poa_irradiance_swd_flat.plot(ax=axs[0, 0])
axs[0,0].set_title('POA Irradiance (Flat)')
modeled_poa_irradiance_swd.plot(ax=axs[0, 1])
axs[0,1].set_title('Modeled Data (Tilted)')
poa_irradiance_swd_corrected.plot(ax=axs[1, 0])
axs[1,0].set_title('POA Irradiance (Tilted)')
modeled_poa_irradiance_swd.plot(ax=axs[1, 1])
axs[1,1].set_title('Modeled Data (Tilted)')
for axs in axs.flat:
axs.set(ylabel='Irradiance $W/m^2$')
# axs.xaxis.set_major_formatter(DateFormatter('%H:%M'))
plt.tight_layout(pad=0, w_pad=0, h_pad=3)
fig.autofmt_xdate()
更新
我认为错误可能来自 DateFormatter
转换日期值的时区。尝试将其添加到程序的顶部。
import matplotlib as mpl
mpl.rcParams['timezone'] = 'UTC'
(这是我第一个 Whosebug 问题!)
我有一个 pandas 数据框,其中包含一天中 15 分钟间隔的太阳辐照度值。此数据帧的索引是“DatetimeIndex”(dtype='datetime64[ns, America/New_York]',并本地化到其各自的时区。因此,索引值以“1997-01-20 00:15:00-05:00”开始,“ 1997-01-20 00:30:00-05:00" ... "1997-01-21 00:00:00-5:00" (注意最后一个条目是第二天凌晨 12 点)。
单独绘制此数据框(名为 poa_irradiance_swd_corrected
)时,一切看起来都很棒。这是我的代码及其输出的示例:
代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import pvlib as pv
import datetime as dt
import math
import pytz
import time
plt.figure()
poa_irradiance_swd_corrected.plot().get_figure().set_facecolor('white')
输出:
此数据框中最高的“poa_global”辐照度测量值介于 12:00 PM(中午)和 1:30-ish 之间。这是准确的。
我还有另外两个数据帧(名为 poa_irradiance_swd_flat
和 modeled_poa_irradiance_swd
)具有类似的辐照度测量值。为了直观地比较辐照度测量值,我使用 matplotlib 的 subplot 函数将所有 3 个数据帧放入一个图中。 然而,X-axis 的子图非常不准确。代码和输出如下所示:
代码:
fig, axs = plt.subplots(2,2, sharex=True,sharey=True, facecolor='white',figsize=(12,8))
fig.suptitle('Sunny Winter Day',size='xx-large',weight='bold')
axs[0,0].plot(poa_irradiance_swd_flat)
axs[0,0].set_title('POA Irradiance (Flat)')
axs[0,1].plot(modeled_poa_irradiance_swd)
axs[0,1].set_title('Modeled Data (Tilted)')
axs[1,0].plot(poa_irradiance_swd_corrected)
axs[1,0].set_title('POA Irradiance (Tilted)')
axs[1,1].plot(modeled_poa_irradiance_swd)
axs[1,1].set_title('Modeled Data (Tilted)')
for axs in axs.flat:
axs.set(ylabel='Irradiance $W/m^2$')
axs.xaxis.set_major_formatter(DateFormatter('%H:%M'))
plt.tight_layout(pad=0, w_pad=0, h_pad=3)
fig.autofmt_xdate()
输出:
请注意 x-axis 如何在 6 小时后完全关闭。
我有 cross-checked 数据帧本身,而且,最高辐照度时间与 12:00 下午(中午)和大约 1:30-ish 之间的时间重合...... 不是 在 18:00 附近(这是 6:00 下午,没有意义)。我什至在 axs[1,0].plot(poa_irradiance_swd_corrected)
代码行中使用了完全相同的数据框。
如何让X-axis显示准确的时间?
编辑(回应scespinoza):
所以我尝试从数据框中传递相应的 .index
和 .values
值,并成功绘制...但仍然存在相同的问题。
然后,我尝试将 ax
命令传递给 plot 函数本身,如下所示:每个子图的 poa_irradiance_swd_flat.plot(ax=axs[0, 0])
。将 matplotlib 作为 mpl 导入后,我还在代码的顶部添加了 mpl.rcParams['timezone'] = 'UTC'
。
现在,我收到一个 ValueError:
ValueError Traceback (most recent call last)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/IPython/core/formatters.py:339, in BaseFormatter.__call__(self, obj)
337 pass
338 else:
--> 339 return printer(obj)
340 # Finally look for special method names
341 method = get_real_method(obj, self.print_method)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/IPython/core/pylabtools.py:151, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
148 from matplotlib.backend_bases import FigureCanvasBase
149 FigureCanvasBase(fig)
--> 151 fig.canvas.print_figure(bytes_io, **kw)
152 data = bytes_io.getvalue()
153 if fmt == 'svg':
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/backend_bases.py:2295, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2289 renderer = _get_renderer(
2290 self.figure,
2291 functools.partial(
2292 print_method, orientation=orientation)
2293 )
2294 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2295 self.figure.draw(renderer)
2297 if bbox_inches:
2298 if bbox_inches == "tight":
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/artist.py:73, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
71 @wraps(draw)
72 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 73 result = draw(artist, renderer, *args, **kwargs)
74 if renderer._rasterizing:
75 renderer.stop_rasterizing()
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/artist.py:50, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
47 if artist.get_agg_filter() is not None:
48 renderer.start_filter()
---> 50 return draw(artist, renderer)
51 finally:
52 if artist.get_agg_filter() is not None:
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/figure.py:2810, in Figure.draw(self, renderer)
2807 # ValueError can occur when resizing a window.
2809 self.patch.draw(renderer)
-> 2810 mimage._draw_list_compositing_images(
2811 renderer, self, artists, self.suppressComposite)
2813 for sfig in self.subfigs:
2814 sfig.draw(renderer)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
135 image_group = []
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/artist.py:50, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
47 if artist.get_agg_filter() is not None:
48 renderer.start_filter()
---> 50 return draw(artist, renderer)
51 finally:
52 if artist.get_agg_filter() is not None:
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axes/_base.py:3046, in _AxesBase.draw(self, renderer)
3043 for spine in self.spines.values():
3044 artists.remove(spine)
-> 3046 self._update_title_position(renderer)
3048 if not self.axison:
3049 for _axis in self._get_axis_list():
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axes/_base.py:2986, in _AxesBase._update_title_position(self, renderer)
2983 for ax in axs:
2984 if (ax.xaxis.get_ticks_position() in ['top', 'unknown']
2985 or ax.xaxis.get_label_position() == 'top'):
-> 2986 bb = ax.xaxis.get_tightbbox(renderer)
2987 else:
2988 bb = ax.get_window_extent(renderer)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axis.py:1103, in Axis.get_tightbbox(self, renderer, for_layout_only)
1100 if not self.get_visible():
1101 return
-> 1103 ticks_to_draw = self._update_ticks()
1105 self._update_label_position(renderer)
1107 # go back to just this axis's tick labels
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/axis.py:1046, in Axis._update_ticks(self)
1041 """
1042 Update ticks (position and labels) using the current data interval of
1043 the axes. Return the list of ticks that will be drawn.
1044 """
1045 major_locs = self.get_majorticklocs()
-> 1046 major_labels = self.major.formatter.format_ticks(major_locs)
1047 major_ticks = self.get_major_ticks(len(major_locs))
1048 self.major.formatter.set_locs(major_locs)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/ticker.py:224, in Formatter.format_ticks(self, values)
222 """Return the tick labels for all the ticks at once."""
223 self.set_locs(values)
--> 224 return [self(value, i) for i, value in enumerate(values)]
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/ticker.py:224, in <listcomp>(.0)
222 """Return the tick labels for all the ticks at once."""
223 self.set_locs(values)
--> 224 return [self(value, i) for i, value in enumerate(values)]
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/dates.py:636, in DateFormatter.__call__(self, x, pos)
635 def __call__(self, x, pos=0):
--> 636 result = num2date(x, self.tz).strftime(self.fmt)
637 return _wrap_in_tex(result) if self._usetex else result
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/dates.py:528, in num2date(x, tz)
526 if tz is None:
527 tz = _get_rc_timezone()
--> 528 return _from_ordinalf_np_vectorized(x, tz).tolist()
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/numpy/lib/function_base.py:2163, in vectorize.__call__(self, *args, **kwargs)
2160 vargs = [args[_i] for _i in inds]
2161 vargs.extend([kwargs[_n] for _n in names])
-> 2163 return self._vectorize_call(func=func, args=vargs)
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/numpy/lib/function_base.py:2246, in vectorize._vectorize_call(self, func, args)
2243 # Convert args to object arrays first
2244 inputs = [asanyarray(a, dtype=object) for a in args]
-> 2246 outputs = ufunc(*inputs)
2248 if ufunc.nout == 1:
2249 res = asanyarray(outputs, dtype=otypes[0])
File ~/opt/miniconda3/envs/pvlib/lib/python3.10/site-packages/matplotlib/dates.py:350, in _from_ordinalf(x, tz)
347 dt = (np.datetime64(get_epoch()) +
348 np.timedelta64(int(np.round(x * MUSECONDS_PER_DAY)), 'us'))
349 if dt < np.datetime64('0001-01-01') or dt >= np.datetime64('10000-01-01'):
--> 350 raise ValueError(f'Date ordinal {x} converts to {dt} (using '
351 f'epoch {get_epoch()}), but Matplotlib dates must be '
352 'between year 0001 and 9999.')
353 # convert from datetime64 to datetime:
354 dt = dt.tolist()
ValueError: Date ordinal 14228655 converts to 40926-09-26T00:00:00.000000 (using epoch 1970-01-01T00:00:00), but Matplotlib dates must be between year 0001 and 9999.
无法真正重现您的问题,但也许您可以尝试将系列的索引和值分别传递给 plot 函数。
...
axs[0,0].plot(poa_irradiance_swd_flat.index, poa_irradiance_swd_flat.values)
...
此外,请注意,您可以将 ax
属性传递给 Series
的 .plot()
函数,因此您可以将代码重构为如下内容:
fig, axs = plt.subplots(2,2, sharex=True,sharey=True, facecolor='white',figsize=(12,8))
fig.suptitle('Sunny Winter Day',size='xx-large',weight='bold')
poa_irradiance_swd_flat.plot(ax=axs[0, 0])
axs[0,0].set_title('POA Irradiance (Flat)')
modeled_poa_irradiance_swd.plot(ax=axs[0, 1])
axs[0,1].set_title('Modeled Data (Tilted)')
poa_irradiance_swd_corrected.plot(ax=axs[1, 0])
axs[1,0].set_title('POA Irradiance (Tilted)')
modeled_poa_irradiance_swd.plot(ax=axs[1, 1])
axs[1,1].set_title('Modeled Data (Tilted)')
for axs in axs.flat:
axs.set(ylabel='Irradiance $W/m^2$')
# axs.xaxis.set_major_formatter(DateFormatter('%H:%M'))
plt.tight_layout(pad=0, w_pad=0, h_pad=3)
fig.autofmt_xdate()
更新
我认为错误可能来自 DateFormatter
转换日期值的时区。尝试将其添加到程序的顶部。
import matplotlib as mpl
mpl.rcParams['timezone'] = 'UTC'