добавление даты к оси X на диаграмме сгруппированных областей - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь построить диаграмму сгруппированных областей, например, a, за исключением меток на осях X, Y и заголовке.

До сих пор я получил enter image description here, но фактические данные не отображаются на графике, как ожидалось.

Когда я раскомментирую строку area_plot.set_xlim(xmin=datemin, xmax=datemax), данные отображаются, но без единиц измерения для оси X.

Я не знаю, так ли это, потому что я хочу, чтобы в качестве единицы оси x были «даты», и в настоящее время мои даты интерпретируются как прямые числа, и мне нужно включить ax.xaxis_date() где-то для преобразования единиц, нокогда я раскомментирую area_plot.xaxis_date(), я получаю следующую ошибку:

There was a problem running this cell
ValueError DateFormatter found a value of x=0, which is an illegal date.  This usually occurs because you have not informed the axis that it is plotting dates, e.g., with ax.xaxis_date()

Я также попытался раскомментировать plt.xticks(np.arange(0, len(x1), 12)), чтобы использовать индекс вместо дат login_month для создания соответствующих ссылок, но это даетмне ошибка:

Error in callback <function install_repl_displayhook.<locals>.post_execute at 0x7f5624809b70> (for post_execute):
There was a problem running this cell
ValueError DateFormatter found a value of x=0, which is an illegal date.  This usually occurs because you have not informed the axis that it is plotting dates, e.g., with ax.xaxis_date() ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/pyplot.py in post_execute()
    147             def post_execute():
    148                 if matplotlib.is_interactive():
--> 149                     draw_all()
    150 
    151             # IPython >= 2

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/_pylab_helpers.py in draw_all(cls, force)
    134         for f_mgr in cls.get_all_fig_managers():
    135             if force or f_mgr.canvas.figure.stale:
--> 136                 f_mgr.canvas.draw_idle()
    137 
    138 atexit.register(Gcf.destroy_all)

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/backend_bases.py in draw_idle(self, *args, **kwargs)
   2053         if not self._is_idle_drawing:
   2054             with self._idle_draw_cntx():
-> 2055                 self.draw(*args, **kwargs)
   2056 
   2057     def draw_cursor(self, event):

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py in draw(self)
    435             # if toolbar:
    436             #     toolbar.set_cursor(cursors.WAIT)
--> 437             self.figure.draw(self.renderer)
    438             # A GUI class may be need to update a window using this draw, so
    439             # don't forget to call the superclass.

/opt/conda/envs/python3/lib/python3.6/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:

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/figure.py in draw(self, renderer)
   1491 
   1492             mimage._draw_list_compositing_images(
-> 1493                 renderer, self, artists, self.suppressComposite)
   1494 
   1495             renderer.close_group('figure')

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    139     if not_composite or not has_images:
    140         for a in artists:
--> 141             a.draw(renderer)
    142     else:
    143         # Composite any adjacent images together

/opt/conda/envs/python3/lib/python3.6/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:

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/axes/_base.py in draw(self, renderer, inframe)
   2633             renderer.stop_rasterizing()
   2634 
-> 2635         mimage._draw_list_compositing_images(renderer, self, artists)
   2636 
   2637         renderer.close_group('axes')

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    139     if not_composite or not has_images:
    140         for a in artists:
--> 141             a.draw(renderer)
    142     else:
    143         # Composite any adjacent images together

/opt/conda/envs/python3/lib/python3.6/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:

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/axis.py in draw(self, renderer, *args, **kwargs)
   1188         renderer.open_group(__name__)
   1189 
-> 1190         ticks_to_draw = self._update_ticks(renderer)
   1191         ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
   1192                                                                 renderer)

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/axis.py in _update_ticks(self, renderer)
   1026 
   1027         interval = self.get_view_interval()
-> 1028         tick_tups = list(self.iter_ticks())  # iter_ticks calls the locator
   1029         if self._smart_bounds and tick_tups:
   1030             # handle inverted limits

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/axis.py in iter_ticks(self)
    973         self.major.formatter.set_locs(majorLocs)
    974         majorLabels = [self.major.formatter(val, i)
--> 975                        for i, val in enumerate(majorLocs)]
    976 
    977         minorLocs = self.minor.locator()

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/axis.py in <listcomp>(.0)
    973         self.major.formatter.set_locs(majorLocs)
    974         majorLabels = [self.major.formatter(val, i)
--> 975                        for i, val in enumerate(majorLocs)]
    976 
    977         minorLocs = self.minor.locator()

/opt/conda/envs/python3/lib/python3.6/site-packages/matplotlib/dates.py in __call__(self, x, pos)
    628     def __call__(self, x, pos=0):
    629         if x == 0:
--> 630             raise ValueError('DateFormatter found a value of x=0, which is '
    631                              'an illegal date.  This usually occurs because '
    632                              'you have not informed the axis that it is '

Вот как выглядит df['login_month'] (то, что я пытаюсь отобразить как ось X):

index   login_month
0       2016-01-01 00:00:00
1       2016-02-01 00:00:00
2       2016-03-01 00:00:00
3       2016-04-01 00:00:00
4       2016-05-01 00:00:00
5       2016-06-01 00:00:00
6       2016-07-01 00:00:00
7       2016-08-01 00:00:00
8       2016-09-01 00:00:00
9       2016-10-01 00:00:00
10      2016-11-01 00:00:00
11      2016-12-01 00:00:00
12      2017-01-01 00:00:00
13      2017-02-01 00:00:00
14      2017-03-01 00:00:00
15      2017-04-01 00:00:00
16      2017-05-01 00:00:00
17      2017-06-01 00:00:00
18      2017-07-01 00:00:00
19      2017-08-01 00:00:00
20      2017-09-01 00:00:00
21      2017-10-01 00:00:00
22      2017-11-01 00:00:00
23      2017-12-01 00:00:00
24      2018-01-01 00:00:00
25      2018-02-01 00:00:00
26      2018-03-01 00:00:00
27      2018-04-01 00:00:00
28      2018-05-01 00:00:00
29      2018-06-01 00:00:00
               ...         
1265    2019-09-01 00:00:00
1266    2019-10-01 00:00:00
1267    2019-04-01 00:00:00
1268    2019-05-01 00:00:00
1269    2019-06-01 00:00:00
1270    2019-07-01 00:00:00
1271    2019-08-01 00:00:00
1272    2019-09-01 00:00:00
1273    2019-10-01 00:00:00
1274    2019-05-01 00:00:00
1275    2019-06-01 00:00:00
1276    2019-07-01 00:00:00
1277    2019-08-01 00:00:00
1278    2019-09-01 00:00:00
1279    2019-10-01 00:00:00
1280    2019-06-01 00:00:00
1281    2019-07-01 00:00:00
1282    2019-08-01 00:00:00
1283    2019-09-01 00:00:00
1284    2019-10-01 00:00:00
1285    2019-07-01 00:00:00
1286    2019-08-01 00:00:00
1287    2019-09-01 00:00:00
1288    2019-10-01 00:00:00
1289    2019-08-01 00:00:00
1290    2019-09-01 00:00:00
1291    2019-10-01 00:00:00
1292    2019-09-01 00:00:00
1293    2019-10-01 00:00:00
1294    2019-10-01 00:00:00
Name: login_month, Length: 1295, dtype: object

Вот фактический кодЯ уже написал.

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

area_plot = (df.pivot(index='login_month',
          columns='user_month_created',
          values='cumulative_logins')
   .plot.area(figsize=(20,18))
)

#labels
plt.title('cumulative monthly logins by user creation cohort month')
plt.xlabel('login month')
plt.ylabel('cumulative monthly logins (in tens of millions)')

#ticks

# plt.xticks(x, 'bbbb')
years = mdates.YearLocator()   # every year
months = mdates.MonthLocator()  # every month
years_fmt = mdates.DateFormatter('%Y')

# format the ticks
area_plot.xaxis.set_major_locator(years)
area_plot.xaxis.set_major_formatter(years_fmt)
area_plot.xaxis.set_minor_locator(months)

# round to nearest years.
datemin = np.datetime64(df['login_month'][0], 'M')
datemax = np.datetime64(df['login_month'][1294], 'M') + np.timedelta64(1, 'Y')
area_plot.set_xlim(xmin=datemin, xmax=datemax)

x1=df['login_month']
# area_plot.xaxis_date()

# plt.xticks(np.arange(0, len(x1), 12))
plt.yticks(np.arange(0, 11000000, 250000))

plt.grid(True)

И вот (очевидно) неполный результат, к которому я пришел, который полностью опускает данные:

enter image description here

РЕДАКТИРОВАТЬ:

После добавления df['login_month'] = pd.to_datetime(df['login_month']) в самом верху у меня есть

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

df['login_month'] = pd.to_datetime(df['login_month'])

area_plot = (df.pivot(index='login_month',
          columns='user_month_created',
          values='cumulative_logins')
   .plot.area(figsize=(20,18))
)

#labels
plt.title('cumulative monthly logins by user creation cohort month')
plt.xlabel('login month')
plt.ylabel('cumulative monthly logins (in tens of millions)')

#ticks
years = mdates.YearLocator()   # every year
months = mdates.MonthLocator()  # every month
years_fmt = mdates.DateFormatter('%Y')

# format the ticks
# x_dates = df['login_month'].dt.strftime('%m-%d').sort_values().unique()
area_plot.xaxis.set_major_locator(years)
# area_plot.xaxis.set_major_formatter(plt.FixedFormatter(x_dates))
area_plot.xaxis.set_major_formatter(years_fmt)
area_plot.xaxis.set_minor_locator(months)

# round to nearest years.
datemin = np.datetime64(df['login_month'][0], 'M')
datemax = np.datetime64(df['login_month'][1294], 'M') + np.timedelta64(1, 'Y')
area_plot.set_xlim(xmin=datemin, xmax=datemax)

# x1=df['login_month']
# area_plot.xaxis_date()

# plt.xticks(np.arange(10, len(x1), 12))
plt.yticks(np.arange(0, 11000000, 250000))
plt.grid(True)

и следующий график, но ось Xпо-прежнему не отображается: enter image description here

...