Python使用Web API数据可视化

    Web应用编程接口 (API)自动请求网站的特定信息而不是整个网页,再对这些信息进行可视化。由于这样编写的程序始终使用最新的数据来生成可视化,因此即便数据瞬息万变,它呈现的信息也都是最新的。

    Web API是网站的一部分,用于与使用非常具体的URL请求特定信息的程序交互。这种请求称为API调用。请求的数据将以易于处理的格式(如JSON或CSV)返回。依赖于外部数据源的大多数应用程序都依赖于API调用,如集成社交媒体网站的应用序。

处理API响应

执行API调用并处理结果,找出GitHub上星级最高的Python项目:

python_repos.py

import requests

#执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'

r = requests.get(url)    #使用requests 来执行调用,将响应对象存储在变量r中
print("Status code:",r.status_code)#响应对象包含一个名为status_code的属性,它让我们知道请求是否成功(状态码200表示请求成功)
#将API响应存储在一个变量中
response_dict = r.json()

#处理结果
print(response_dict.keys())

处理响应字典

将API调用返回的信息存储到字典中后,就可以处理这个字典中的数据了。下面生成一些概述这些信息的输出。可确认收到了期望的信息,进而可以开始研究感兴趣的信息:

import requests

#执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'

r = requests.get(url)
print("Status code:",r.status_code)
#将API响应存储在一个变量中
response_dict = r.json()
print("Total repositories:",response_dict['total_count'])#指出GitHub包含多少个Python仓库
#探索有关仓库的信息
repo_dicts=response_dict['items']#response_dict字典存储在列表中,列表里每个字典都包含有关一个Python仓库的信息
print("Repositories returned:",len(repo_dicts))
#研究第一个仓库
repo_dict = repo_dicts[0]
print("\nKeys:",len(repo_dict))
for key in sorted(repo_dict.keys()):
	print(key)

GitHub的API返回有关每个仓库的大量信息:repo_dict 包含68个键(见❶)。通过仔细查看这些键,可大致知道可提取有关项目的哪些信息(要准确地获悉API将返回哪些信息,要么阅读文档,要么像此处这样使用代码来查看这些信息)。

  Status code: 200
  Total repositories: 713062
  Repositories returned: 30

❶ Keys: 68
  archive_url
  assignees_url
  blobs_url
  --snip--
  url
  watchers
  watchers_count

概述最受欢迎的仓库

对这些数据进行可视化时,我们需要涵盖多个仓库。下面就来编写一个循环,打印API调用返回的每个仓库的特定信息,以便能够在可视化中包含所有这些信息:

--snip--
#研究第一个仓库
repo_dict = repo_dicts[0]
print("\nKeys:",len(repo_dict))
for key in sorted(repo_dict.keys()):
	print(key)

print("\nSelected information about first repository:")
for repo_dict in repo_dicts:
	print('\nName:', repo_dict['name'])
	print('Owner:', repo_dict['owner']['login'])
	print('Stars:', repo_dict['stargazers_count'])
	print('Repository:', repo_dict['html_url'])
	print('Description:', repo_dict['description'])

监视API的速率限制

大多数API都存在速率限制,即你在特定时间内可执行的请求数存在限制。要获悉你是否接近了GitHub的限制,请在浏览器中输入https://api.github.com/rate_limit ,你将看到类似于下面的响应:

{
  "resources": {
    "core": {
      "limit": 60,
      "remaining": 60,
      "reset": 1521446243
    },
    "search": {#搜索API的速率限制
      "limit": 10,#极限为每分钟10个请求
      "remaining": 10,#在当前这一分钟内,我们还可执行10个请求
      "reset": 1521442703#配额将重置的Unix时间或新纪元时间(1970年1月1日午夜后多少秒)
    },
    "graphql": {
      "limit": 0,
      "remaining": 0,
      "reset": 1521446243
    }
  },
  "rate": {
    "limit": 60,
    "remaining": 60,
    "reset": 1521446243
  }
}

使用Pygal可视化仓库

有了一些有趣的数据后,我们来进行可视化,呈现GitHub上Python项目的受欢迎程度。我们将创建一个交互式条形图:条形的高度表示项目获得了多少颗星。单击条形将带你进入项目在GitHub上的主页。下面是首次尝试这样做:

import requests
import pygal
from pygal.style import LightColorizedStyle as LCS,LightenStyle as LS
#执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'

r = requests.get(url)
print("Status code:",r.status_code)
#将API响应存储在一个变量中
response_dict = r.json()
print("Total repositories:",response_dict['total_count'])#指出GitHub包含多少个Python仓库
#探索有关仓库的信息
repo_dicts=response_dict['items']#response_dict字典存储在列表中,列表里每个字典都包含有关一个Python仓库的信息
names,stars = [],[]
for repo_dict in repo_dicts:
	names.append(repo_dict['name'])
	stars.append(repo_dict['stargazers_count'])

#可视化
my_style = LS('#333366',base_style=LCS)
chart = pygal.Bar(style=my_style,x_label_rotation=45,show_legend=False)#创建条形图,让标签绕x轴旋转45度(x_label_rotation=45 ),隐藏图例(show_legend=False )
chart.title = 'Most-Starred Python Projects on GitHub'#指定标题
chart.x_labels=names#横座标标签
chart.add('',stars)#添加数据,标签设置成空字符串
chart.render_to_file('python_repos.svg')

改进Pygal图表

进行多个方面的定制,因此先来稍微调整代码的结构,创建一个配置对象,在其中包含要传递给Bar() 的所有定制:

--snip--
#可视化
my_style = LS('#333366',base_style=LCS)
my_config = pygal.Config()#创建Pygal类Config实例,通过修改my_config定制图表外观
my_config.x_label_rotation = 45#让标签绕x轴旋转45度(x_label_rotation=45 )
my_config.show_legend = False#隐藏图例(show_legend=False )
my_config.title_font_size = 24#图表标题
my_config.lable_font_size =14#副标签(X轴项目名及Y轴大部分数字)
my_config.major_label_font_size = 18#主标签(Y轴5000整数倍的刻度)
my_config.truncate_label =15#将较长的项目名缩短为15个字符
my_config.show_y_guides = False#隐藏图表中的水平线
my_config.width = 1000#自定义宽度

chart = pygal.Bar(my_config,style=my_style)#通过my_config传递所有配置设置
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels=names
chart.add('',stars)
chart.render_to_file('python_repos.svg')

添加自定义工具提示

在Pygal中,将鼠标指向条形将显示它表示的信息,这通常称为工具提示 。在这个示例中,当前显示的是项目获得了多少个星。下面来创建一个自定义工具提示,以同时显示项目的描述。来看一个简单的示例,它可视化前三个项目,并给每个项目对应的条形都指定自定义标签。为此,我们向add() 传递一个字典列表,而不是值列表:

bar_descriptions.py

import pygal
from pygal.style import LightColorizedStyle as LCS,LightenStyle as LS

my_style = LS('#333366',base_style = LCS)
chart = pygal.Bar(style=my_style,x_label_rotation =45,show_legend=False)

chart.title ='Python Projects'
chart.x_labels = ['httpie','django','flask']
plot_dicts = [
	{'value': 16101, 'label': 'Description of httpie.'},
	{'value': 15028, 'label': 'Description of django.'},
	{'value': 14798, 'label': 'Description of flask.'},
	]

chart.add('', plot_dicts)
chart.render_to_file('bar_descriptions.svg')

        定义了一个名为plot_dicts的列表,其中包含三个字典,分别针对项目HTTPie、Django和Flask。每个字典都包含两个键:'value' 和'label' 。Pygal根据与键'value' 相关联的数字来确定条形的高度,并使用与'label' 相关联的字符串给条形创建工具提示。第一个字典将创建一个条形,用于表示一个获得了16 101颗星、工具提示为Description of httpie的项目。方法add() 接受一个字符串和一个列表。这里调用add() 时,我们传入了一个由表示条形的字典组成的列表(plot_dicts )。结果显示了一个工具提示:除默认工具提示(获得的星数)外,Pygal还显示了我们传入的自定义提示。


--snip--
#探索有关仓库的信息
repo_dicts=response_dict['items']#response_dict字典存储在列表中,列表里每个字典都包含有关一个Python仓库的信息

names,plot_dicts = [],[]
for repo_dict in repo_dicts:
	names.append(repo_dict['name'])
	plot_dict ={
		'value':repo_dict['stargazers_count'],
		'label':str(repo_dict['description']),
		}
	plot_dicts.append(plot_dict)

#可视化
my_style = LS('#333366',base_style=LCS)
--snip--

chart.add('',plot_dicts)
chart.render_to_file('python_repos.svg')

在图表中添加可单击的链接

--snip--
        plot_dict ={
		'value':repo_dict['stargazers_count'],
		'label':str(repo_dict['description']),
		'xlink':repo_dict['html_url'],
		}
--snip--

Pygal根据与键'xlink' 相关联的URL将每个条形都转换为活跃的链接。单击图表中的任何条形时,都将在浏览器中打开一个新的标签页,并在其中显示相应项目的GitHub页面。至此,你对API获取的数据进行了可视化,它是交互性的,包含丰富的信息!

Hacker News API
在Hacker News网站,用户分享编程和技术方面的文章,并就这些文章展开积极的讨论。Hacker News的API让你能够访问有关该网站所有文章和评论的信息,且不要求你通过注册获得密钥。执行一个API调用,返回Hacker News上当前热门文章的ID,再查看每篇排名靠前的文章:
import requests
from operator import itemgetter
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS


#执行API调用并存储响应
url = 'https://hacker-news.firebaseio.com/v0/topstories.json'
r = requests.get(url)
#打印请求状态(200表示成功)
print("Status code:",r.status_code)

#处理有关每篇文章的信息
#将包含ID信息的响应文本转换为列表
submission_ids = r.json()
#创建空列表存储文章信息(字典)
submission_dicts = []

#通过ID遍历前30篇文章,并执行API调用
for submission_id in submission_ids[:3]:
	#对于每篇文章都执行一个API调用
	url = ('https://hacker-news.firebaseio.com/v0/item/' +
		str(submission_id) + '.json')
	submission_r = requests.get(url)
	print(submission_r.status_code)
	response_dict = submission_r.json()

	submission_dict = {
		'title': response_dict['title'],#标题
		'link': 'http://news.ycombinator.com/item?id=' + 
			str(submission_id),#讨论页面链接
		#不确定某个键是否包含在字典中时,使用方法dict.get()
		#它在指定的键存在时返回与之相关联的值
		#并在指定的键不存在时返回你指定的值(这里是0)
		'comments': response_dict.get('descendants', 0)#评论数
		}
	submission_dicts.append(submission_dict)
#根据comments降序排列
submission_dicts = sorted(submission_dicts, key = itemgetter('comments'), 
	reverse = True)
for submission_dict in submission_dicts:
	print("\nTitle:",submission_dict['title'])
	print("Discussion link:",submission_dict['link'])
	print("Comments:",submission_dict['comments'])

titles,plot_dicts = [],[]
for submission_dict in submission_dicts:
	titles.append(submission_dict['title'])
	plot_dicts = {
		'value':submission_dict['comments'],
		'label':submission_dict['title'],
		'xlink':submission_dict['link'],
		}
	plot_dicts.append(plot_dict)

my_style = LS('#333366',base_style = LCS)
my_style.title_font_size = 24
my_style.label_font_size = 14
my_style.major_lable_font_size = 18

my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_lenged = False
my_config.truncate_label = 15 #将较长的项目名缩短为15个字符
my_config.show_y_guides = False #隐藏图表中的水平线
my_config.width = 1000
my_config.y_title = 'Number of Comments'

chart = pygal.Bar(my_config, style = my_style)
chart.title = 'Most Active Discussions on Hacker News'
chart.x_labels = titles
chart.add('',plot_dicts)
chart.render_to_file('hn_discussions.svg')

发布了35 篇原创文章 · 获赞 21 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章