python - 在分组面积图中将日期添加到 x 轴
问题描述
我正在尝试绘制像这样的分组面积图,除了 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
日期来创建适当的 xticks,但它给了我错误:
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)
解决方案
推荐阅读
- node.js - 如何在客户端和服务器之间进行双向通信
- firebase - Firebase Pub/Sub 一次触发多个带有消息的作业
- android - 我无法从交易中读取数据
- python - 如何在 chrome 的 Inspect Element> Network > XHR > Response > Headers > General 中从网页中查找请求 URL
- css - 有没有办法为除顶部标题之外的所有标题指定顶部边距?
- python-3.x - 使用 IBM Cloud Function 的 REST API 时如何修复“错误”:“'parameter_name'”?
- php - 如何从 laravel 5.7 中具有相同 where 条件的两个表中获取数据
- python - 无法绘制线性回归散点图和预测线
- python - 比较主数据框和子数据框并仅基于两列值提取新行
- python - 包括前 N 行过滤器匹配