使用 Plotly 可视化存储库
让我们用收集到的数据制作一个可视化图表,显示 Python 项目在 GitHub 上的相对受欢迎程度。我们将制作一个交互式条形图:每个条形图的高度将代表该项目获得的星星数量,点击条形图的标签就能进入该项目在 GitHub 上的主页。
将我们正在运行的程序保存为 python_repos_visual.py,然后将其修改如下:
import requests
import plotly.express as px
# Make an API call and check the response.
url = "https://api.github.com/search/repositories"
url += "?q=language:python+sort:stars+stars:>10000"
headers = {"Accept": "application/vnd.github.v3+json"}
r = requests.get(url, headers=headers)
print(f"Status code: {r.status_code}") # 1
# Process overall results.
response_dict = r.json()
print(f"Complete results: {not response_dict['incomplete_results']}") # 2
# Process repository information.
repo_dicts = response_dict['items']
repo_names, stars = [], [] # 3
for repo_dict in repo_dicts:
repo_names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])
# Make visualization.
fig = px.bar(x=repo_names, y=stars) # 4
fig.show()
python
我们导入 Plotly Express,然后像以往一样调用 API。我们将继续打印 API 调用响应的状态,以便了解是否存在问题❶。当我们处理整个结果时,我们会继续打印确认我们得到了一组完整结果的信息❷。我们删除了其余的 print() 调用,因为我们不再处于探索阶段;我们知道我们已经得到了想要的数据。
然后,我们创建两个空列表❸ 来存储初始图表中的数据。我们需要每个项目的名称来标注条形图(repo_names),还需要星星的数量来确定条形图的高度(stars)。在循环中,我们会将每个项目的名称和星星的数量追加到这些列表中。
我们仅用两行代码❹ 就完成了初始可视化。这与 Plotly Express 的理念一致,即在完善可视化的外观之前,应尽快看到可视化的效果。在这里,我们使用 px.bar() 函数创建一个条形图。我们将 repo_names 列表作为 x 参数传递,将星星作为 y 参数传递。
图 17-1 显示了生成的图表。我们可以看到,前几个项目明显比其他项目更受欢迎,但它们都是 Python 生态系统中的重要项目。

设计图表样式
一旦知道绘图中的信息是正确的,Plotly 就会支持多种样式和自定义绘图的方法。我们将对初始 px.bar()
调用进行一些修改,然后在创建 fig
对象后对其进行进一步调整。
我们将首先为图表添加标题和每个坐标轴的标签:
--snip--
# Make visualization.
title = "Most-Starred Python Projects on GitHub"
labels = {'x': 'Repository', 'y': 'Stars'}
fig = px.bar(x=repo_names, y=stars, title=title, labels=labels)
fig.update_layout(title_font_size=28, xaxis_title_font_size=20, yaxis_title_font_size=20) # 1
fig.show()
python
我们首先为每个坐标轴添加标题和标签,就像在第 15 章和第 16 章中所做的那样。然后,我们使用 fig.update_layout()
方法修改图表的特定元素❶。Plotly 使用一种惯例,即图表元素的各个方面用下划线连接。当你熟悉了 Plotly 的文档后,你就会发现图表中不同元素的命名和修改方式是一致的。在这里,我们将标题的字体大小设置为 28,每个坐标轴标题的字体大小设置为 20。结果如图 17-2 所示。

添加自定义工具提示
在 Plotly 中,你可以将光标悬停在单个条形图上,以显示该条形图所代表的信息。这通常称为工具提示,在本例中,它目前显示的是项目的星级数。让我们创建一个自定义工具提示,显示每个项目的描述以及项目所有者。
我们需要提取一些额外的数据来生成工具提示:
--snip--
# Process repository information.
repo_dicts = response_dict['items']
repo_names, stars, hover_texts = [], [], [] # 1
for repo_dict in repo_dicts:
repo_names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])
# Build hover texts.
owner = repo_dict['owner']['login'] # 2
description = repo_dict['description']
hover_text = f"{owner}<br />{description}" # 3
hover_texts.append(hover_text)
# Make visualization.
title = "Most-Starred Python Projects on GitHub"
labels = {'x': 'Repository', 'y': 'Stars'}
fig = px.bar(x=repo_names, y=stars, title=title, labels=labels, hover_name=hover_texts) # 4
fig.update_layout(title_font_size=28, xaxis_title_font_size=20, yaxis_title_font_size=20)
fig.show()
python
我们首先定义一个新的空列表,hover_texts,来保存我们想要为每个项目显示的文本❶。 在处理数据的循环中,我们提取每个项目的所有者和描述❷。 Plotly 允许您在文本元素中使用 HTML 代码,因此我们为标签生成一个字符串,并在项目所有者的用户名和描述之间使用换行符 (<br />) ❸。 然后我们将此标签附加到列表 hover_texts。
在 px.bar() 调用中,我们添加 hover_name 参数并传递给它 hover_texts ❹。 这与我们为全球地震活动地图中的每个点自定义标签所用的方法相同。当 Plotly 创建每个条时,它会从此列表中提取标签,并且仅当查看器将鼠标悬停在条上时才显示它们。图 17-3 显示了这些自定义工具提示之一。

添加可点击的链接
由于 Plotly 允许在文本元素上使用 HTML,因此我们可以轻松地为图表添加链接。让我们利用 x 轴标签让浏览者访问 GitHub 上的任何项目主页。我们需要从数据中提取 URL,并在生成 x 轴标签时使用它们:
--snip--
# Process repository information.
repo_dicts = response_dict['items']
repo_links, stars, hover_texts = [], [], [] # 1
for repo_dict in repo_dicts:
# Turn repo names into active links.
repo_name = repo_dict['name']
repo_url = repo_dict['html_url'] # 2
repo_link = f"<a href='{repo_url}'>{repo_name}</a>" # 3
repo_links.append(repo_link)
stars.append(repo_dict['stargazers_count'])
--snip--
# Make visualization.
title = "Most-Starred Python Projects on GitHub"
labels = {'x': 'Repository', 'y': 'Stars'}
fig = px.bar(x=repo_links, y=stars, title=title, labels=labels, hover_name=hover_texts)
fig.update_layout(title_font_size=28, xaxis_title_font_size=20, yaxis_title_font_size=20)
fig.show()
python
我们将正在创建的列表的名称从 repo_names 更新为 repo_links,以更准确地传达我们为图表❶整理的信息类型。然后,我们从 repo_dict 中提取项目的 URL 并将其分配给临时变量 repo_url ❷。接下来,我们生成项目的链接❸。我们使用 HTML 锚标记(其格式为 <a href='URL'>链接文本</a>)来生成链接。然后我们将此链接附加到 repo_links。
当我们调用 px.bar() 时,我们使用 repo_links 作为图表中的 x 值。结果看起来与以前相同,但现在查看者可以单击图表底部的任何项目名称来访问该项目在 GitHub 上的主页。现在,我们对通过 API 检索的数据进行了交互式、信息丰富的可视化!
自定义标记颜色
创建图表后,几乎可以通过更新方法对图表的任何方面进行自定义。我们之前使用过 update_layout()
方法。另一个方法 update_traces()
,可用于自定义图表中的数据。
让我们将条形图改为深蓝色,并增加一些透明度:
--snip--
fig.update_layout(title_font_size=28, xaxis_title_font_size=20, yaxis_title_font_size=20)
fig.update_traces(marker_color='SteelBlue', marker_opacity=0.6)
fig.show()
python
在 Plotly 中,跟踪指的是图表上的数据集合。update_traces() 方法可以接受许多不同的参数;任何以 marker_
开头的参数都会影响图表上的标记。在这里,我们将每个标记的颜色设置为 "SteelBlue";任何已命名的 CSS 颜色在这里都可以使用。我们还将每个标记的不透明度设置为 0.6。不透明度为 1.0 时,标记完全不透明,不透明度为 0 时,标记完全不可见。
有关 Plotly 和 GitHub API 的更多信息
Plotly 的文档内容广泛、条理清晰,但要从哪里开始阅读却很难。从 https://plotly.com/python/plotly-express 上的文章 "Plotly Express in Python" 开始阅读是个不错的选择。这篇文章概述了你可以用 Plotly Express 制作的所有图表,你还可以找到关于每种图表类型的长文链接。
如果你想了解如何更好地定制 Plotly 图表,文章 "Styling Plotly Express Figures in Python" 将扩展你在第 15-17 章中看到的内容。您可以在 https://plotly.com/python/styling-plotly-express 上找到这篇文章。
有关 GitHub API 的更多信息,请参阅 https://docs.github.com/en/rest 上的文档。在这里,你将学习如何从 GitHub 获取各种信息。要扩展你在本项目中看到的内容,请查看侧边栏中参考资料的搜索部分。如果你有一个 GitHub 账户,就可以使用自己的数据以及其他用户资源库中的公开数据。