从Marplotlib到Plotly: 教你入门Python数据可视化
作为一名数据科学家,在了解 Plotly 之前,我曾经非常依赖 Matplotlib 完成我的数据可视化任务。
虽然 Matplotlib 是在 Python 中创建可视化最快且最直接的工具,但它最适合初始的探索性分析和静态绘图。如果你想通过 Matplotlib 制作基本静态图以外的东西,需要进行非常复杂的操作。
另一方面,Plotly 是一个较新的开源图形库,可以高效地创建更复杂的交互式可视化。操作也很简单,只需几行代码就能创建美观的交互式绘图。近年来,Plotly在数据科学界非常受欢迎,用的人也越来越多,未来可能会超过 Matplotlib 的人气。
本文将逐步带领你通过 Plotly 创建带有自定义工具框(Customized Tooltips)和范围滑(Range Slider)的交互式组合图(Interactive Combo Chart)。在本教程中,你将学习Plotly的关键概念和特性,文章也会为您提供完整的代码。如果你想了解更多数据分析相关内容,可以阅读以下这些文章:
数据可视化Data Visualization需要哪些图表技能?
数据科学必备技能:如何用Power BI做数据可视化
用漏斗可视化,讲好数据故事
数据可视化干货:如何为你的Data Visualization找到正确的色板?
我们构建的交互式组合图如下所示:
Plotly Express Vs. Plotly Go
Python的Plotly库是一个交互式开源图形库,涵盖了多种图表类型和数据可视化用例。Plotly Python有一个 Plotly Express 包装器,是 Plotly 的高级接口。
Plotly Express 可以通过简单的语法,快速创建最常见图形的原型,但对于高级图表或自定义图表来说,缺乏功能性和灵活性。
与 Plotly Express 相比,Plotly Go(图形对象)是一个较低级别的图形包,通常需要更多编程,但可自定义,且灵活性更强。在本教程中,我们将通过 Plotly Go 创建如上所示的组合图。你还可以将代码保存为模板,用于在其他用例中创建类似的图表。
下载数据
我们用来创建图表的数据可以从 CDC 网站下载。这是一个开放数据集,用于记录美国每日 Covid-19 新增病例以及 7 天内平均变化量。
https://covid.cdc.gov/covid-data-tracker/#trends_dailycases
导入库(Libraries)并读取数据
首先,导入本教程所需的所有库,并将数据读入 python。如果这是你第一次使用 Plotly,你需要在导入库之前安装 Plotly。你可以在Jupyter笔记本上运行以下命令(我已经安装了 Plotly,所以页面显示“符合要求”)。
#Import Libraries
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from datetime import datetime
#Read the data
df=pd.read_csv('.../data_table_for_daily_case_trends__the_united_states.csv')
这个数据集相对比较简单,“几乎”可以直接用于可视化。我们注意到“日期(Date)”字段是一个字符串,因此,我们需要将其转换为类型“日期”。此外,为了达到最佳效果,我总是重命名单词之间有空格的字段,因此我们将通过删除空格,重命名最后三个字段。
最后,我们希望在绘图的工具框中显示新增病例”和“7 天内平均变化量”。如果数字以千位分隔符显示,看起来会更直观。我们可以通过创建两个新的重新格式化的字段(对象类型),解决这个问题,这些字段将显示带有千位分隔符的数字。
#Clean and Reformat the Data Fields
df['Date']=df['Date'].str[4:6]+df['Date'].str[:3]+df['Date'].str[7:11]
df['Snapshot_Date'] = pd.to_datetime(df['Date'], format='%d%b%Y').dt.date #Create a new column that has the 'date' type
df = df.rename({'New Cases': 'New_Cases', '7-Day Moving Avg': 'Seven_Day_Avg','Historic Cases':'Historic_Cases'}, axis=1) #Rename the fields
df.loc[:, "New_Cases_formatted"] = df["New_Cases"].map('{:,d}'.format) #Create a new column that shows thousand seperator in numbers (though the new column is now an object not integer)
df.loc[:, "Seven_Day_Avg_formatted"] = df["Seven_Day_Avg"].map('{:,d}'.format) #Create a new column that shows thousand seperator in numbers (though the new column is now an object not integer)
通过 Plotly Go 创建标准组合图(Standard Combo Chart)
如果想要通过 Plotly Go(图形对象)绘图,我们需要先用 go.Figure() 创建一个图形,然后使用 fig.add_trace() 添加两条迹线(Trace)。什么是迹线?以下定义来自 Plotly 文档:
“迹线是我们给数据集合的名称,以及我们希望绘制数据的规格。请注意,迹线本身也是一个对象,其名称根据你希望数据在绘图表面上的显示方式而定。”
迹线就像你想通过数据绘制的特定可视化类型,数量高达 40 多种,包括散点图、条形图、饼图、等值线图等。在本示例中,由于我们正在绘制组合图(折线图和条形图的组合),我们将添加两条迹线。
fig = go.Figure() #Create a Plotly Graph_Objects Figure
#Add the first trace/bar chart to the figure
fig.add_trace(
go.Bar(
x=df['Snapshot_Date'],
y=df['New_Cases'],
name="New Cases",
marker_line_color='#11457E',
marker_line_width=2,
opacity=0.7)
)
#Add the second trace/line chart to the figure
fig.add_trace(
go.Scatter(
x=df['Snapshot_Date'],
y=df['Seven_Day_Avg'],
name="7-Day Moving Avg",
mode='lines',
line = dict(color='firebrick', width=3)
))
请注意,折线图是通过 go.Scatter() 绘制的。这是因为 Plotly 折线图的生成是由于连接散点图。这也意味着,数据点按照它们在数据集中出现的顺序与线连接。因此,在将数据传递给Plotly之前,如果原始的排序不能得到所需的输出,你可能需要在此之前对数据进行显式排序。
自定义悬停工具框(Hover-over Tooltips)
默认情况下,Plotly 会自动在工具框中显示 x 和 y 轴的值。例如,在上图中,如果将鼠标悬停在折线图中的任何数据点上,则会出现一个工具框,并显示新增案例的日期以及 7 天内平均变化量。
我们可以通过在数据框中创建一个叫“text”的新列,从而自定义工具框的外观。这个“text”列显示了我们想要在工具框中显示的信息,并定义了工具框的外观和感觉。然后,通过将这些信息分配给 hoverinfo 参数,将此列“文本”传递给 go.Scatter() 迹线。
下列代码可以在数据框中创建“文本”列。HTML 元素,也被称为 Boldface 元素,在此处用于将“State”字段的文本设为粗体。
HTML 元素在文本中产生一个换行符,之后的文本再次从文本块的下一行开始。
hover_text = []
for index, row in df.iterrows():
hover_text.append(('<b>{State}</b><br><br>'+
'Snapshot Date: {Snapshot_Date}<br>'+
'New Cases: {New_Cases_formatted}<br>'+
'7-Day Moving Avg: {Seven_Day_Avg_formatted}<br>'
).format(
State=row['State'],
Snapshot_Date=row['Snapshot_Date'],
New_Cases_formatted=row['New_Cases_formatted'],
Seven_Day_Avg_formatted=row['Seven_Day_Avg_formatted']
))
df['text'] = hover_text
现在,我们将“text”列传递给go.Scatter()中的hoverinfo参数,并检查它在工具框中的外观:
fig = go.Figure()
fig.add_trace(
go.Bar(
x=df['Snapshot_Date'],
y=df['New_Cases'],
name="New Cases",
hoverinfo='none', #Do not show tooltip when hovering over the bar chart as this information is repetitive when hovering over the line chart
marker_line_color='#11457E',
marker_line_width=2,
opacity=0.7)
)
fig.add_trace(
go.Scatter(
x=df['Snapshot_Date'],
y=df['Seven_Day_Avg'],
name="7-Day Moving Avg",
mode='lines',
text=df['text'],
hoverinfo='text', #Pass the 'text' column to the hoverinfo parameter to customize the tooltip
line = dict(color='firebrick', width=3)
))
看起来不错!让我们再对表格做一些额外的调整,看起来更专业。我们将工具框的背景颜色从红色更改为浅蓝色。我们还可以添加图表标题,并将 x 轴刻度更改为每月(而不是每季度)。所有这些操作都可以通过 fig.update_layout() 实现,代码如下所示。
fig.update_layout(hoverlabel_bgcolor='#DAEEED', #Change the tooltip background color to be light grey
title_text='Daily COVID-19 Cases in the U.S.', #Add a chart title
title_font_family="Times New Roman",
title_font_size = 25,
title_font_color="darkblue",
title_x=0.25, #Specify the title position
xaxis=dict(
tickfont_size=10,
tickangle = 270,
showgrid = True,
zeroline = True,
showline = True,
showticklabels = True,
dtick="M1", #Change the x-axis ticks to be monthly
tickformat="%b\n%Y"
),)
添加范围滑块(Range Slider)/选择器(Selector)
我们还可以添加范围选择器/滑块,方便用户可以放大到特定的时间序列范围,从而使可视化更具信息性和交互性!这一步操作可以在 fig.update_xaxes() 中通过几行代码轻松实现。
#Add the range slider and selector to the plot
fig.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="1m", step="month", stepmode="backward"),
dict(count=6, label="6m", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
)
)
fig.show()
现在,我们基本上已经完成了所有操作!你已经通过 Plotly Go 创建了一个交互式组合图表,通过自定义工具框和范围滑块/选择器可视化美国每日 Covid-19 病例趋势。正如你所看到的那样,Plotly 图形库功能强大、界面优雅且高度可定制。通过Plotly图形库,你可以轻松高效执行创建复杂的交互式可视化任务。我希望这篇文章对您有所帮助,并做好准备,将 Plotly 添加到你的数据科学家的工具包中。
参考资料及资料来源:
1. Plotly 的官方文档页面:https://plotly.com/python/
2. 数据来源:来自疾病控制与预防中心 (CDC) 网站 (https://covid.cdc.gov/covid-data-tracker/#trends_dailycases) 的开放 Covid-19 跟踪器数据集
原文作者:Sharone Li
翻译作者:Lia
美工编辑:过儿
校对审稿:Jiawei Tong
原文链接:https://towardsdatascience.com/leap-from-matplotlib-to-plotly-a-hands-on-tutorial-for-beginners-d208cd9e6522