Я пытаюсь построить диаграмму сгруппированных областей, например, , за исключением меток на осях X, Y и заголовке.
До сих пор я получил , но фактические данные не отображаются на графике, как ожидалось.
Когда я раскомментирую строку 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)
И вот (очевидно) неполный результат, к которому я пришел, который полностью опускает данные:
РЕДАКТИРОВАТЬ:
После добавления 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по-прежнему не отображается: