背景
在上一篇使用matplotlib绘制时间序列图表中,本来想只展示最大值,一直没找到方法,就先标注了所有的点的数值,看起来有点不够直接。今天终于搞定了,记录一下。
思路
源数据:index 为 ‘data’,数据为’title’
1 | cacu.head(5) |
matpoltlib标注数值
在绘图的时候,可以使用
ax.text()
方法在坐标系中标注文字,使用方法如下:1
2
3# 显示全部数值
for a,b in zip(cacu.index, cacu.values):
ax.text(a, b, b[0])寻找最大值:
在pandas中有现成的方法可以找到最大值和最大值的索引:
最大值的索引:
1
2
3
4cacu.idxmax()
Out[6]:
title 2018-07-01
dtype: datetime64[ns]最大值:
1
2
3
4cacu.max()
Out[8]:
title 50
dtype: int64也可根据索引取值:
1
2
3
4
5cacu.loc[cacu.idxmax()]
Out[7]:
title
date
2018-07-01 50画图标注
根据最上面的标注,应该直接输入最大值的坐标(x为索引,y为值)就可以了,结果有了如下的报错:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17ax.text(cacu.idxmax(), cacu.max(), cacu.max())
/Users/zhengk/PycharmProjects/web_scraping_and_data_analysis/venv/lib/python3.7/site-packages/pandas/core/ops.py:1649: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
result = method(y)
Traceback (most recent call last):
File "/Users/zhengk/PycharmProjects/web_scraping_and_data_analysis/venv/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3291, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-9-cebfed8d464d>", line 1, in <module>
ax.text(cacu.idxmax(), cacu.max(), cacu.max())
File "/Users/zhengk/PycharmProjects/web_scraping_and_data_analysis/venv/lib/python3.7/site-packages/matplotlib/axes/_axes.py", line 722, in text
x=x, y=y, text=s)
File "/Users/zhengk/PycharmProjects/web_scraping_and_data_analysis/venv/lib/python3.7/site-packages/matplotlib/text.py", line 163, in __init__
self.set_text(text)
File "/Users/zhengk/PycharmProjects/web_scraping_and_data_analysis/venv/lib/python3.7/site-packages/matplotlib/text.py", line 1191, in set_text
if s != self._text:
File "/Users/zhengk/PycharmProjects/web_scraping_and_data_analysis/venv/lib/python3.7/site-packages/pandas/core/generic.py", line 1479, in __nonzero__
.format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().我们仔细看上面最大值的返回结果类型,而并非一个坐标。
1
2type(cacu.idxmax())
Out[11]: pandas.core.series.Series而我们真正需要的应该是
title
列的最大索引:1
2
3
4type(cacu['title'].idxmax())
Out[12]: pandas._libs.tslibs.timestamps.Timestamp
cacu['title'].idxmax()
Out[13]: Timestamp('2018-07-01 00:00:00', freq='MS')对应的最大值也一样:
1
2
3
4cacu['title'].max()
Out[15]: 50
type(cacu['title'].max())
Out[16]: numpy.int64再次画图:
1
2
3x = cacu['title'].idxmax()
y = cacu['title'].max()
ax.text(x, y, y, verticalalignment='bottom', horizontalalignment='center', fontsize='large')结果
结论
这里出现问题其实还是对matplotlib和pandas的基本概念没有弄明白,什么时候获取的是值,什么时候获取的是序列,还需要多加练习。
另外,给图添加标注还有可以使用plt.annotate()
方法:
1 | x = cacu['title'].idxmax() |
完整代码参考:https://github.com/keejo125/web_scraping_and_data_analysis/tree/master/weixin