Matplotlib fill_between(…) не работает с PeriodIndex

#matplotlib

#matplotlib

Вопрос:

Я пытаюсь заставить его работать многими способами, но это просто не так. Кто-нибудь знает, как это исправить?

Вот простой игрушечный код

 index = pd.period_range('1990-1', '2000-1', freq='M')
df = pd.DataFrame({1:[1]*len(index), 2:[10]*len(index)}, index=index)

plt.fill_between(index, x[1], x[2])
  

Это не сработает. Если вы измените index index.to_timestamp() , тогда он будет работать нормально.

Отображаемая ошибка

 ~Miniconda3libsite-packagesmatplotlibaxes_axes.py in fill_between(self, x, y1, y2, where, interpolate, step, **kwargs)
   5226 
   5227         # Handle united data, such as dates
-> 5228         self._process_unit_info(xdata=x, ydata=y1, kwargs=kwargs)
   5229         self._process_unit_info(ydata=y2)
   5230 

~Miniconda3libsite-packagesmatplotlibaxes_base.py in _process_unit_info(self, xdata, ydata, kwargs)
   2123             return kwargs
   2124 
-> 2125         kwargs = _process_single_axis(xdata, self.xaxis, 'xunits', kwargs)
   2126         kwargs = _process_single_axis(ydata, self.yaxis, 'yunits', kwargs)
   2127         return kwargs

~Miniconda3libsite-packagesmatplotlibaxes_base.py in _process_single_axis(data, axis, unit_name, kwargs)
   2106                 # We only need to update if there is nothing set yet.
   2107                 if not axis.have_units():
-> 2108                     axis.update_units(data)
   2109 
   2110             # Check for units in the kwargs, and if present update axis

~Miniconda3libsite-packagesmatplotlibaxis.py in update_units(self, data)
   1496 
   1497         if neednew:
-> 1498             self._update_axisinfo()
   1499         self.stale = True
   1500         return True

~Miniconda3libsite-packagesmatplotlibaxis.py in _update_axisinfo(self)
   1532             self.isDefault_label = True
   1533 
-> 1534         self.set_default_intervals()
   1535 
   1536     def have_units(self):

~Miniconda3libsite-packagesmatplotlibaxis.py in set_default_intervals(self)
   2170                 if info.default_limits is not None:
   2171                     valmin, valmax = info.default_limits
-> 2172                     xmin = self.converter.convert(valmin, self.units, self)
   2173                     xmax = self.converter.convert(valmax, self.units, self)
   2174             if not dataMutated:

~Miniconda3libsite-packagespandasplotting_matplotlibconverter.py in convert(values, units, axis)
    207             values = [PeriodConverter._convert_1d(v, units, axis) for v in values]
    208         else:
--> 209             values = PeriodConverter._convert_1d(values, units, axis)
    210         return values
    211 

~Miniconda3libsite-packagespandasplotting_matplotlibconverter.py in _convert_1d(values, units, axis)
    213     def _convert_1d(values, units, axis):
    214         if not hasattr(axis, "freq"):
--> 215             raise TypeError("Axis must have `freq` set to convert to Periods")
    216         valid_types = (str, datetime, Period, pydt.date, pydt.time, np.datetime64)
    217         if isinstance(values, valid_types) or is_integer(values) or is_float(values):

TypeError: Axis must have `freq` set to convert to Periods
  

Если кто-нибудь может помочь мне с этой ошибкой, я был бы очень благодарен! Спасибо!

Комментарии:

1. Вы уверены, что используете последние версии matplotlib и pandas?

Ответ №1:

Первое исправление: индекс — это имя атрибута фрейма данных, поэтому используйте скорее какое-то «похожее» имя, например:

 idx = pd.period_range('1990-1', '2000-1', freq='M')
  

Затем создайте свой фрейм данных как:

 df = pd.DataFrame({1:[1]*len(idx), 2:[10]*len(idx)}, index=idx)
  

Вы можете заполнить пробел между обеими строками, но сначала нарисуйте сами строки
:

 df.plot()
  

Затем вы можете заполнить пробел между ними:

 plt.fill_between(idx, df[1], df[2]);
  

(обратите внимание, что вы написали x вместо df).

По-видимому, plt требует, чтобы либо обе линии границы были нарисованы заранее, либо хотя бы одна из них. Но картинка выглядит лучше, когда обе линии границы нарисованы другим цветом, чем пространство между ними, поэтому более естественно рисовать обе линии.