首页 > 解决方案 > Matplotlib 无法绘制只有 NaN 值的 DateTime 系列

问题描述

我有一个dtf带有列的 DataFrame Data...

print(dft.Date)
print(type(dft))
print(type(dft.iloc[0]["Date"]))

1340    2018-01-04 00:06:58
1341    2018-01-04 00:17:18
1342    2018-01-04 00:27:38
1343    2018-01-04 00:37:59
1344    2018-01-04 00:48:19
1345    2018-01-04 00:58:41
1346    2018-01-04 01:09:01
1347    2018-01-04 01:19:21
1348    2018-01-04 01:29:41
1349    2018-01-04 01:40:02
Name: Date, dtype: object
<class 'pandas.core.frame.DataFrame'>
<class 'pandas._libs.tslib.Timestamp'>

...以及一列X有时包含许多值的np.NaN值。我想要灵活地绘制图表(其中没有任何内容),即使只有np.NaN在 column 中X当至少存在一个非np.NaN值时,一切正常:

dft["X"] = np.array([1] + [np.NaN for i in range(9)])

plt.plot(dft.Date, dft.X)   #  works as expected

但是只要只有 np.NaN存在,我就会尝试绘制:

dft["X"] = np.array([np.NaN for i in range(10)])

plt.plot(dft.Date, dft.X)

..我收到以下错误:

[<matplotlib.lines.Line2D at 0x1ba20c7f128>]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\formatters.py in __call__(self, obj)
    339                 pass
    340             else:
--> 341                 return printer(obj)
    342             # Finally look for special method names
    343             method = get_real_method(obj, self.print_method)

C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py in <lambda>(fig)
    236 
    237     if 'png' in formats:
--> 238         png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
    239     if 'retina' in formats or 'png2x' in formats:
    240         png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))

C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
    120 
    121     bytes_io = BytesIO()
--> 122     fig.canvas.print_figure(bytes_io, **kw)
    123     data = bytes_io.getvalue()
    124     if fmt == 'svg':

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, **kwargs)
   2214                     orientation=orientation,
   2215                     dryrun=True,
-> 2216                     **kwargs)
   2217                 renderer = self.figure._cachedRenderer
   2218                 bbox_inches = self.figure.get_tightbbox(renderer)

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py in print_png(self, filename_or_obj, *args, **kwargs)
    505 
    506     def print_png(self, filename_or_obj, *args, **kwargs):
--> 507         FigureCanvasAgg.draw(self)
    508         renderer = self.get_renderer()
    509         original_dpi = renderer.dpi

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py in draw(self)
    428             # if toolbar:
    429             #     toolbar.set_cursor(cursors.WAIT)
--> 430             self.figure.draw(self.renderer)
    431         finally:
    432             # if toolbar:

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     53                 renderer.start_filter()
     54 
---> 55             return draw(artist, renderer, *args, **kwargs)
     56         finally:
     57             if artist.get_agg_filter() is not None:

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\figure.py in draw(self, renderer)
   1297 
   1298             mimage._draw_list_compositing_images(
-> 1299                 renderer, self, artists, self.suppressComposite)
   1300 
   1301             renderer.close_group('figure')

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    136     if not_composite or not has_images:
    137         for a in artists:
--> 138             a.draw(renderer)
    139     else:
    140         # Composite any adjacent images together

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     53                 renderer.start_filter()
     54 
---> 55             return draw(artist, renderer, *args, **kwargs)
     56         finally:
     57             if artist.get_agg_filter() is not None:

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axes\_base.py in draw(self, renderer, inframe)
   2435             renderer.stop_rasterizing()
   2436 
-> 2437         mimage._draw_list_compositing_images(renderer, self, artists)
   2438 
   2439         renderer.close_group('axes')

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    136     if not_composite or not has_images:
    137         for a in artists:
--> 138             a.draw(renderer)
    139     else:
    140         # Composite any adjacent images together

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     53                 renderer.start_filter()
     54 
---> 55             return draw(artist, renderer, *args, **kwargs)
     56         finally:
     57             if artist.get_agg_filter() is not None:

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axis.py in draw(self, renderer, *args, **kwargs)
   1131         renderer.open_group(__name__)
   1132 
-> 1133         ticks_to_draw = self._update_ticks(renderer)
   1134         ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
   1135                                                                 renderer)

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axis.py in _update_ticks(self, renderer)
    972 
    973         interval = self.get_view_interval()
--> 974         tick_tups = list(self.iter_ticks())
    975         if self._smart_bounds and tick_tups:
    976             # handle inverted limits

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axis.py in iter_ticks(self)
    915         Iterate through all of the major and minor ticks.
    916         """
--> 917         majorLocs = self.major.locator()
    918         majorTicks = self.get_major_ticks(len(majorLocs))
    919         self.major.formatter.set_locs(majorLocs)

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\dates.py in __call__(self)
   1095     def __call__(self):
   1096         'Return the locations of the ticks'
-> 1097         self.refresh()
   1098         return self._locator()
   1099 

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\dates.py in refresh(self)
   1115     def refresh(self):
   1116         'Refresh internal information based on current limits.'
-> 1117         dmin, dmax = self.viewlim_to_dt()
   1118         self._locator = self.get_locator(dmin, dmax)
   1119 

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\dates.py in viewlim_to_dt(self)
    873             vmin, vmax = vmax, vmin
    874 
--> 875         return num2date(vmin, self.tz), num2date(vmax, self.tz)
    876 
    877     def _get_unit(self):

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\dates.py in num2date(x, tz)
    464         tz = _get_rc_timezone()
    465     if not cbook.iterable(x):
--> 466         return _from_ordinalf(x, tz)
    467     else:
    468         x = np.asarray(x)

C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\dates.py in _from_ordinalf(x, tz)
    277 
    278     ix = int(x)
--> 279     dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC)
    280 
    281     remainder = float(x) - ix

ValueError: ordinal must be >= 1

<matplotlib.figure.Figure at 0x1ba20c5c630>

我已经尝试Date根据这篇文章转换列,并Date通过 usingdft.Date.astype('O')和许多其他解决方法进行转换。没有任何效果。

我不想删除或填充 NaN。

标签: pythonpandasmatplotlib

解决方案


推荐阅读