几种绘制时间线图的方法

前面分享过一篇自动化制作《历史上的今天》时间线图片的文章,小伙伴们普遍反映还不错,尤其是制作时间线的方法,还是非常巧妙的。今天我们再来分享几种不同的制作方法,大家可以自行比较下各种方法的优劣

Matplotlib 作为 Python 家族最为重要的可视化工具,其基本的 API 以及绘制流程还是需要掌握的。尤其是该库的灵活程度以及作为众多工具的基础,重要性不言而喻

下面我们来看下该如何绘制一个时间线图表

导入库以及设置 XY 轴数据

<span class="hljs-keyword">import</span>&#xA0;matplotlib.pyplot&#xA0;<span class="hljs-keyword">as</span>&#xA0;plt<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>]&#xA0;=&#xA0;[<span class="hljs-string">'SimHei'</span>]<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>]&#xA0;=&#xA0;<span class="hljs-literal">False</span><br><br>y1&#xA0;=&#xA0;[<span class="hljs-number">5</span>,&#xA0;<span class="hljs-number">10</span>,&#xA0;<span class="hljs-number">15</span>,&#xA0;<span class="hljs-number">20</span>,&#xA0;<span class="hljs-number">25</span>,&#xA0;<span class="hljs-number">30</span>,&#xA0;<span class="hljs-number">35</span>,&#xA0;<span class="hljs-number">40</span>,&#xA0;<span class="hljs-number">45</span>,&#xA0;<span class="hljs-number">50</span>]<br>x1&#xA0;=&#xA0;[<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>,&#xA0;<span class="hljs-number">4</span>]

因为是通过折线图来实现时间线效果,为了达到一条竖线的情况,这里设置了 X 轴数值都相同,Y 轴数值等差分布

创建画布及标题

fig,&#xA0;ax&#xA0;=&#xA0;plt.subplots(sharey=<span class="hljs-literal">True</span>,&#xA0;figsize=(<span class="hljs-number">7</span>,&#xA0;<span class="hljs-number">4</span>))<br>ax.plot(x1,&#xA0;y1,&#xA0;label=<span class="hljs-string">'First&#xA0;line'</span>,&#xA0;linewidth=<span class="hljs-number">3</span>,&#xA0;color=<span class="hljs-string">'r'</span>,&#xA0;marker=<span class="hljs-string">'o'</span>,&#xA0;markerfacecolor=<span class="hljs-string">'white'</span>,&#xA0;markersize=<span class="hljs-number">12</span>)<br>plt.title(<span class="hljs-string">'&#x841D;&#x535C;&#x5927;&#x6742;&#x70E9;'</span>)<br>plt.suptitle(<span class="hljs-string">'&#x5386;&#x53F2;&#x4E0A;&#x7684;&#x4ECA;&#x5929;'</span>,&#xA0;fontsize=<span class="hljs-number">16</span>,&#xA0;color=<span class="hljs-string">'red'</span>)

此时效果如下

接下来我们设置时间线两边的数据

<br>right_y_year&#xA0;=&#xA0;<span class="hljs-number">0.95</span><br>right_y_text&#xA0;=&#xA0;<span class="hljs-number">0.9</span><br>year_right&#xA0;=&#xA0;<span class="hljs-number">1931</span><br><span class="hljs-keyword">for</span>&#xA0;i&#xA0;<span class="hljs-keyword">in</span>&#xA0;range(<span class="hljs-number">5</span>):<br>&#xA0;&#xA0;&#xA0;&#xA0;plt.text(<span class="hljs-number">0.57</span>,&#xA0;right_y_year,&#xA0;str(year_right+<span class="hljs-number">1</span>),&#xA0;fontsize=<span class="hljs-number">15</span>,&#xA0;horizontalalignment=<span class="hljs-string">'center'</span>,&#xA0;verticalalignment=<span class="hljs-string">'center'</span>,&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;transform=ax.transAxes,&#xA0;color=<span class="hljs-string">'black'</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;plt.text(<span class="hljs-number">0.75</span>,&#xA0;right_y_text,&#xA0;<span class="hljs-string">"&#x4ECE;&#x767E;&#x8349;&#x56ED;&#x5230;&#x4E09;&#x5473;&#x4E66;&#x5C4B;-&#x9C81;&#x8FC5;"</span>&#xA0;+&#xA0;str(i),&#xA0;fontsize=<span class="hljs-number">15</span>,&#xA0;horizontalalignment=<span class="hljs-string">'center'</span>,&#xA0;verticalalignment=<span class="hljs-string">'center'</span>,&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;transform=ax.transAxes,&#xA0;color=<span class="hljs-string">'red'</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;right_y_year&#xA0;-=&#xA0;<span class="hljs-number">0.2</span><br>&#xA0;&#xA0;&#xA0;&#xA0;right_y_text&#xA0;-=&#xA0;<span class="hljs-number">0.2</span><br>&#xA0;&#xA0;&#xA0;&#xA0;year_right&#xA0;+=&#xA0;<span class="hljs-number">1</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<br><br>left_y_year&#xA0;=&#xA0;<span class="hljs-number">0.85</span><br>left_y_text&#xA0;=&#xA0;<span class="hljs-number">0.8</span><br>year_left&#xA0;=&#xA0;<span class="hljs-number">1941</span><br><span class="hljs-keyword">for</span>&#xA0;i&#xA0;<span class="hljs-keyword">in</span>&#xA0;range(<span class="hljs-number">5</span>):<br>&#xA0;&#xA0;&#xA0;&#xA0;plt.text(<span class="hljs-number">0.43</span>,&#xA0;left_y_year,&#xA0;str(year_left+<span class="hljs-number">1</span>),&#xA0;fontsize=<span class="hljs-number">15</span>,&#xA0;horizontalalignment=<span class="hljs-string">'center'</span>,&#xA0;verticalalignment=<span class="hljs-string">'center'</span>,&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;transform=ax.transAxes,&#xA0;color=<span class="hljs-string">'black'</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;plt.text(<span class="hljs-number">0.2</span>,&#xA0;left_y_text,&#xA0;<span class="hljs-string">"&#x4ECE;&#x767E;&#x8349;&#x56ED;&#x5230;&#x4E09;&#x5473;&#x4E66;&#x5C4B;-&#x9C81;&#x8FC5;"</span>&#xA0;+&#xA0;str(i),&#xA0;fontsize=<span class="hljs-number">15</span>,&#xA0;horizontalalignment=<span class="hljs-string">'center'</span>,&#xA0;verticalalignment=<span class="hljs-string">'center'</span>,&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;transform=ax.transAxes,&#xA0;color=<span class="hljs-string">'red'</span>,&#xA0;url=<span class="hljs-string">'https://www.baidu.com'</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;left_y_year&#xA0;-=&#xA0;<span class="hljs-number">0.2</span><br>&#xA0;&#xA0;&#xA0;&#xA0;left_y_text&#xA0;-=&#xA0;<span class="hljs-number">0.2</span><br>&#xA0;&#xA0;&#xA0;&#xA0;year_left&#xA0;+=&#xA0;<span class="hljs-number">1</span>

这里主要使用了 text 函数,为时间线轴两边分别添加数据

如果我们还想要添加个人的其他信息,比如公众号二维码等,可以在指定位置增加图片,同时去掉坐标轴

<br>img&#xA0;=&#xA0;plt.imread(<span class="hljs-string">'&#x4E8C;&#x7EF4;&#x7801;.png'</span>)<br>ax2&#xA0;=&#xA0;plt.axes((<span class="hljs-number">0.7</span>,&#xA0;<span class="hljs-number">0.1</span>,&#xA0;<span class="hljs-number">0.3</span>,&#xA0;<span class="hljs-number">0.3</span>))<br>ax2.imshow(img,&#xA0;origin=<span class="hljs-string">'lower'</span>,&#xA0;alpha=<span class="hljs-number">0.5</span>)<br>ax2.axis(<span class="hljs-string">'off'</span>)<br>ax.axis(<span class="hljs-string">'off'</span>)<br>plt.show()

最终效果如下

可以看出,由于 text 函数是通过坐标来确定文字显示的位置的,所以我们的时间线轴两边的数据分布还是不是特别完美,不知道是否有其他的更加方便的方法来设置

Plotly 作为 Python 家族另一个非常强大的可视化工具,同样可以完成时间线图的绘制

在绘图之前,完美先处理数据

这里使用的数据是2020年全年的微博热搜数据

<span class="hljs-keyword">import</span>&#xA0;pandas&#xA0;<span class="hljs-keyword">as</span>&#xA0;pd<br><br><br>weibo&#xA0;=&#xA0;pd.read_csv(<span class="hljs-string">"weibo_2020.csv"</span>)<br><span class="hljs-function"><span class="hljs-keyword">def</span>&#xA0;<span class="hljs-title">deal_date</span><span class="hljs-params">(frame)</span>:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;tmp&#xA0;=&#xA0;frame.split(<span class="hljs-string">'-'</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span class="hljs-keyword">return</span>&#xA0;tmp[<span class="hljs-number">0</span>]&#xA0;+&#xA0;<span class="hljs-string">'-'</span>&#xA0;+&#xA0;tmp[<span class="hljs-number">1</span>]<br><br>weibo[<span class="hljs-string">'new_date'</span>]&#xA0;=&#xA0;weibo[<span class="hljs-string">'date'</span>].apply(<span class="hljs-keyword">lambda</span>&#xA0;x&#xA0;:&#xA0;deal_date(x))<br>key_list_right&#xA0;=&#xA0;[]<br><span class="hljs-keyword">for</span>&#xA0;i&#xA0;<span class="hljs-keyword">in</span>&#xA0;range(<span class="hljs-number">1</span>,&#xA0;<span class="hljs-number">12</span>,&#xA0;<span class="hljs-number">2</span>):<br>&#xA0;&#xA0;&#xA0;&#xA0;<span class="hljs-keyword">if</span>&#xA0;i&#xA0;< <span class="hljs-number">10:<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;mydate&#xA0;=&#xA0;<span class="hljs-string">'2020-0%s'</span>&#xA0;%&#xA0;str(i)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span class="hljs-keyword">else</span>:<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;mydate&#xA0;=&#xA0;<span class="hljs-string">'2020-%s'</span>&#xA0;%&#xA0;str(i)<br>&#xA0;&#xA0;&#xA0;&#xA0;keyword&#xA0;=&#xA0;weibo[weibo[<span class="hljs-string">'new_date'</span>]&#xA0;==&#xA0;mydate].sort_values(by=<span class="hljs-string">'searchCount'</span>,&#xA0;ascending=<span class="hljs-literal">False</span>)[<span class="hljs-string">'keyword'</span>].tolist()[<span class="hljs-number">0</span>]<br>&#xA0;&#xA0;&#xA0;&#xA0;searchCount&#xA0;=&#xA0;weibo[weibo[<span class="hljs-string">'new_date'</span>]&#xA0;==&#xA0;mydate].sort_values(by=<span class="hljs-string">'searchCount'</span>,&#xA0;ascending=<span class="hljs-literal">False</span>)[<span class="hljs-string">'searchCount'</span>].tolist()[<span class="hljs-number">0</span>]<br>&#xA0;&#xA0;&#xA0;&#xA0;mount&#xA0;=&#xA0;str(i)&#xA0;+&#xA0;<span class="hljs-string">'&#x6708;'</span><br>&#xA0;&#xA0;&#xA0;&#xA0;content&#xA0;=&#xA0;<span class="hljs-string">','</span>.join([keyword,&#xA0;str(searchCount)&#xA0;+&#xA0;<span class="hljs-string">'&#x641C;&#x7D22;&#x91CF;'</span>,&#xA0;mount])<br>&#xA0;&#xA0;&#xA0;&#xA0;key_list_right.append(content)<br>print(key_list_right)<br></ <span>

Output:

['&#x6700;&#x65B0;&#x75AB;&#x60C5;&#x5730;&#x56FE;,18130201&#x641C;&#x7D22;&#x91CF;,1&#x6708;',
 '&#x8096;&#x6218;&#x5DE5;&#x4F5C;&#x5BA4;&#x9053;&#x6B49;,13117531&#x641C;&#x7D22;&#x91CF;,3&#x6708;',
 '&#x4F55;&#x9E3F;&#x71CA;&#x53BB;&#x4E16;,15302424&#x641C;&#x7D22;&#x91CF;,5&#x6708;',
 '&#x9AD8;&#x8003;&#x4F5C;&#x6587;,15647446&#x641C;&#x7D22;&#x91CF;,7&#x6708;',
 '&#x4E58;&#x98CE;&#x7834;&#x6D6A;&#x7684;&#x59D0;&#x59D0;&#x6210;&#x56E2;&#x4E4B;&#x591C;,8226994&#x641C;&#x7D22;&#x91CF;,9&#x6708;',
 '&#x7279;&#x6717;&#x666E;,7310000&#x641C;&#x7D22;&#x91CF;,11&#x6708;']

可以看到,通过上面的数据处理,我们成功提取了1、3、5、7、9以及11月的当月搜索量最高的热搜标题,同理可以获取到双月份的热搜标题数据

下面开始作图

<span class="hljs-keyword">import</span>&#xA0;plotly.express&#xA0;<span class="hljs-keyword">as</span>&#xA0;px<br><span class="hljs-keyword">import</span>&#xA0;plotly.graph_objects&#xA0;<span class="hljs-keyword">as</span>&#xA0;go<br><span class="hljs-keyword">from</span>&#xA0;plotly.subplots&#xA0;<span class="hljs-keyword">import</span>&#xA0;make_subplots<br><span class="hljs-keyword">import</span>&#xA0;pandas&#xA0;<span class="hljs-keyword">as</span>&#xA0;pd<br><span class="hljs-keyword">from</span>&#xA0;plotly.graph_objs&#xA0;<span class="hljs-keyword">import</span>&#xA0;*<br><br>layout&#xA0;=&#xA0;Layout(<br>&#xA0;&#xA0;&#xA0;&#xA0;paper_bgcolor=<span class="hljs-string">'rgba(0,0,0,0)'</span>,<br>&#xA0;&#xA0;&#xA0;&#xA0;plot_bgcolor=<span class="hljs-string">'rgba(0,0,0,0)'</span>,<br>&#xA0;&#xA0;&#xA0;&#xA0;title={<span class="hljs-string">'text'</span>:&#xA0;<span class="hljs-string">'&#x5FAE;&#x535A;&#x70ED;&#x641C;'</span>,&#xA0;<span class="hljs-string">'x'</span>:&#xA0;<span class="hljs-number">0.5</span>},<br>&#xA0;&#xA0;&#xA0;&#xA0;yaxis={<span class="hljs-string">'title'</span>:&#xA0;<span class="hljs-string">'Proportion&#xA0;(%)'</span>}<br>)<br>fig&#xA0;=&#xA0;go.Figure(layout=layout)<br>fig.add_traces([go.Scatter(x=[<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>],&#xA0;y=[<span class="hljs-number">5</span>,&#xA0;<span class="hljs-number">10</span>,&#xA0;<span class="hljs-number">15</span>,&#xA0;<span class="hljs-number">20</span>,&#xA0;<span class="hljs-number">25</span>,&#xA0;<span class="hljs-number">30</span>],&#xA0;text=key_list_right,&#xA0;textposition=<span class="hljs-string">"bottom&#xA0;right"</span>,&#xA0;mode=<span class="hljs-string">"lines+text"</span>),<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;go.Scatter(x=[<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>],&#xA0;y=[<span class="hljs-number">5</span>,&#xA0;<span class="hljs-number">10</span>,&#xA0;<span class="hljs-number">15</span>,&#xA0;<span class="hljs-number">20</span>,&#xA0;<span class="hljs-number">25</span>,&#xA0;<span class="hljs-number">30</span>],&#xA0;textposition=<span class="hljs-string">"top&#xA0;left"</span>,&#xA0;mode=<span class="hljs-string">"lines+text"</span>,&#xA0;text=key_list_left)])&#xA0;<br>fig.update_traces(showlegend=<span class="hljs-literal">False</span>)<br>fig.update_layout(xaxis=dict(visible=<span class="hljs-literal">False</span>),&#xA0;yaxis=dict(visible=<span class="hljs-literal">False</span>))<br>fig.show()

通过 Plotly 绘图就相对简单很多了,直接使用 text 参数把我们得到的热搜数据添加上即可

最终效果如下

效果很朴素,是因为我们没有进行过多的样式设置,大家可以自行探索下不同样式啊

上面的两种方法都需要有一定的代码基础,下面介绍的 Excel 方法则可以说是人人都能完成,一起来看看吧

先来看看最终的效果

首先准备数据,我们在新建的 Excel 文档中创建如下数据

然后插入散点图

先插入一个空白散点图,然后将 X 轴设置为【年份】,Y 轴设置为【位置】,再把 Y 轴和网格线都删除

接下来我们美化一下 X 轴

我们双击 X 轴,调出格式窗口,在坐标轴选项标签中设置【单位】,将【小】改为1,设置【刻度线】,将【主刻度线】设置为交叉。再点击【油漆桶】,选择一个线条的颜色,将宽度调整为2,将【结尾箭头类型】调整为向右箭头

再接下来我们把 X 轴连接起来

首先选择一个散点,添加误差线。然后把横向的误差线设置为无轮廓,再选中竖向的误差线,把【垂直误差线】设置为负偏差,再把误差量设置为100%,最后再给竖向误差线调整样式即可

下面开始添加数据

我们把公司的各种大事件添加到数据表当中

向图表中添加【数据标签】,即数据中事件那一列,然后再去掉 Y 值即可

最后我们还可以通过 Excel 自带的各种图标进行美化操作

好了,以上就是今天分享的所有内容,如果对你有帮助,帮忙点赞和在看支持哦~

Original: https://blog.csdn.net/zhouwei_1989_/article/details/126253557
Author: zhouluobo
Title: 几种绘制时间线图的方法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/765981/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球