pygal的简单使用
pygal的简单使用
例子来自此书: 《Python编程从入门到实战》【美】Eric Matthes
pygal是一个SVG图表库。SVG是一种矢量图格式。全称Scalable Vector Graphics -- 可缩放矢量图形。
用浏览器打开svg,可以方便的与之交互。
以下代码均在Jupyter Notebook中运行
模拟掷骰子
来看一个简单的例子。它模拟了掷骰子。
import random
class Die:
"""
一个骰子类
"""
def __init__(self, num_sides=6):
self.num_sides = num_sides
def roll(self):
return random.randint(1, self.num_sides)
模拟掷骰子并可视化
import pygal
die = Die()
result_list = []
# 掷1000次
for roll_num in range(1000):
result = die.roll()
result_list.append(result)
frequencies = []
# 范围1~6,统计每个数字出现的次数
for value in range(1, die.num_sides + 1):
frequency = result_list.count(value)
frequencies.append(frequency)
# 条形图
hist = pygal.Bar()
hist.title = 'Results of rolling one D6 1000 times'
# x轴坐标
hist.x_labels = [1, 2, 3, 4, 5, 6]
# x、y轴的描述
hist.x_title = 'Result'
hist.y_title = 'Frequency of Result'
# 添加数据, 第一个参数是数据的标题
hist.add('D6', frequencies)
# 保存到本地,格式必须是svg
hist.render_to_file('die_visual.svg')
使用浏览器打开这个文件,鼠标指向数据,可以看到显示了标题“D6”, x轴的坐标以及y轴坐标。
可以发现,六个数字出现的频次是差不多的(理论上概率是1/6, 随着实验次数的增加,趋势越来越明显)
同时掷两个骰子
稍微改下代码就行,再实例化一个骰子
die_1 = Die()
die_2 = Die()
result_list = []
for roll_num in range(5000):
# 两个骰子的点数和
result = die_1.roll() + die_2.roll()
result_list.append(result)
frequencies = []
# 能掷出的最大数
max_result = die_1.num_sides + die_2.num_sides
for value in range(2, max_result + 1):
frequency = result_list.count(value)
frequencies.append(frequency)
# 可视化
hist = pygal.Bar()
hist.title = 'Results of rolling two D6 dice 5000 times'
hist.x_labels = [x for x in range(2, max_result + 1)]
hist.x_title = 'Result'
hist.y_title = 'Frequency of Result'
# 添加数据
hist.add('two D6', frequencies)
# 格式必须是svg
hist.render_to_file('2_die_visual.svg')
从图中可以看出,两个骰子之和为7的次数最多,和为2的次数最少。因为能掷出2的只有一种情况 -> (1, 1);而掷出7的情况有(1, 6) , (2, 5), (3, 4), (4, 3), (5, 2), (6, 1)共6种情况,其余数字的情况都没有7的多,故掷得7得概率最大。
处理json数据--世界人口地图
需要用到人口数据
点击这里下载population.json,该数据来源于okfn.org这个网站
打开看下数据,其实这是个很长的列表,包含了许多国家从1960~2015年的人口数据。看第一数据,如下。后面的数据和第一个键都一样。
[
{
"Country Name":"Arab World",
"Country Code":"ARB",
"Year":"1960",
"Value":"92496099"
},
...
只有四个键,其中Country Code
指的是国别码,这里是3位的。Value
就是人口数了。
import json
filename = r'F:\Jupyter Notebook\matplotlib_pygal_csv_json\population.json'
with open(filename) as f:
# json.load()可以将json文件转为Python能处理的形式,这里位列表,列表里是字典
pop_data = json.load(f)
cc_populations = {}
for pop_dict in pop_data:
if pop_dict['Year'] == '2015':
country_name = pop_dict['Country Name']
# 有些值是小数,先转为float再转为int
population = int(float(pop_dict['Value']))
print(country_name + ': ' + population)
上面的程序打印了2015年各个国家的人口数,当然要分析2014年的,代码中数字改改就行。
Arab World: 392168030
Caribbean small states: 7116360
Central Europe and the Baltics: 103256779
Early-demographic dividend: 3122757473.68203
East Asia & Pacific: 2279146555
...
需要注意的是,人口数据有些值是小数(不可思议)。人口数据类型是字符串str,如果直接转int,像'35435.12432'
这样的字符串是不能强转位int的,必须先转为float,再丢失精度转为int。
获取两个字母的国别码
我们的数据中,国别码是三位的,而pygal的地图工具使用两位国别码。要使用pygal绘制世界地图。需要安装依赖包。
pip install pygal_maps_world
就可以了
国别码位于i18n
模块
from pygal_maps_world.i18n import COUNTRIES
这样就导入了, COUNTRIES是一个字典,键是两位国别码,值是具体国家名。
key -> value
af Afghanistan
af Afghanistan
al Albania
al Albania
dz Algeria
dz Algeria
ad Andorra
ad Andorra
ao Angola
写一个函数,根据具体国家名返回pygal提供的两位国别码
def get_country_code(country_name):
"""
根据国家名返回两位国别码
"""
for code, name in COUNTRIES.items():
if name == country_name:
return code
return None
世界人口地图绘制
先给出全部代码,需要用到World
类
import json
from pygal_maps_world.i18n import COUNTRIES
from pygal_maps_world.maps import World
# 颜色相关
from pygal.style import RotateStyle
from pygal.style import LightColorizedStyle
def get_country_code(country_name):
"""
根据国家名返回两位国别码
"""
for code, name in COUNTRIES.items():
if name == country_name:
return code
return None
filename = r'F:\Jupyter Notebook\matplotlib_pygal_csv_json\population.json'
with open(filename) as f:
pop_data = json.load(f)
cc_populations = {}
for pop_dict in pop_data:
if pop_dict['Year'] == '2015':
country_name = pop_dict['Country Name']
# 有些值是小数,先转为float再转为int
population = int(float(pop_dict['Value']))
code = get_country_code(country_name)
if code:
cc_populations[code] = population
# 为了使颜色分层更加明显
cc_populations_1,cc_populations_2, cc_populations_3 = {}, {}, {}
for cc, population in cc_populations.items():
if population < 10000000:
cc_populations_1[cc] = population
elif population < 1000000000:
cc_populations_2[cc] = population
else:
cc_populations_3[cc] = population
wm_style = RotateStyle('#336699', base_style=LightColorizedStyle)
world = World(style=wm_style)
world.title = 'World Populations in 2015, By Country'
world.add('0-10m', cc_populations_1)
world.add('10m-1bn', cc_populations_2)
world.add('>1bn', cc_populations_3)
world.render_to_file('world_population_2015.svg')
有几个变量比较重要
cc_populations
是一个dict,里面存放了两位国别码与人口的键值对。cc_populations_1,cc_populations_2, cc_populations_3
这是3个字典,把人口按照数量分阶梯,人口一千万以下的存放在cc_populations_1
中,一千万~十亿级别的存放在cc_populations_2
中,十亿以上的存放在cc_populations_3
中,这样做的目的是使得颜色分层更加明显,更方便找出各个阶梯里人口最多的国家。由于分了三个层次,在添加数据的的时候也add三次,把这三个字典分别传进去。world = World(style=wm_style)
这是一个地图类,导入方法from pygal_maps_world.maps import World
wm_style = RotateStyle('#336699', base_style=LightColorizedStyle)
这里修改了pygal默认的主题颜色,第一个参数是16进制的RGB颜色,前两位代表R,中间两位代表G,最后两位代表B。数字越大颜色越深。第二个参数设置基础样式为亮色主题,pygal默认使用较暗的颜色主题,通过此方法可以修改默认样式。
中国大佬,No. 1
图中可以看出,分的三个颜色层次为。紫色系,十亿以上;蓝色系,一千万到十亿之间;绿色系,一千万一下。这三种颜色里面颜色最深的就对应了三个阶梯里人口最多的国家。
仔细观察,图中有些是空白的。并不是这些地方全部没人,而是我们的json数据中有些国家的名称与pygal中COUNTIES模块的国家名不对应导致。这算是一个遗憾,不过可以修改get_country_code
函数,使得遇到不对应的国家名时,不返回None。对于这些国家,查阅COUNTRIES的代码,找出对应的国别码,返回之,应该就Ok了。比如下面这样
# 传入的参数country_name是json数据中的,可能与COUNTRIES里面的国家名不一致,按照上面的代码直接就返回None,导致绘图时这个国家的人口数据空白
if country_name == 'Yemen, Rep':
return 'ye'
不过我懒得试了233
使用Web API分析数据
以GitHub为例,我想查看最受欢迎的Python库。以stars排序。
访问这个网址就可查看。数据大概长这样
{
"total_count": 1767997,
"incomplete_results": false,
"items": [{
{
"id": 21289110,
"name": "awesome-python",
"full_name": "vinta/awesome-python",
"owner": {
"login": "vinta",
...
},
...
"html_url": "https://github.com/vinta/awesome-python",
...
"stargazers_count": 35234,
...
}, {...}
...]
}
第三个数据,items
。里面是得到stars最多的top 30。name
即库名称,owner
下的login
是库的拥有者,html_url是该库的网址(注意owner下也有个html_url。不过那个是用户的GitHub网址,我们要定位到该用户的具体这个库,所以不要用owner下的html_url),stargazers_count
至关重要,所得的stars数目。
顺便说下第一个键total_count
,表示Python语言的仓库的总数;第二个键,incomplete_results
,表示响应的值不完全,一般来说是false,表示响应的数据完整。
import requests
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
response = requests.get(url)
# 200为响应成功
print(response.status_code, '响应成功!')
response_dict = response.json()
total_repo = response_dict['total_count']
repo_list = response_dict['items']
print('总仓库数: ', total_repo)
print('top', len(repo_list))
for repo_dict in repo_list:
print('\nName: ', repo_dict['name'])
print('Owner: ', repo_dict['owner']['login'])
print('Stars: ', repo_dict['stargazers_count'])
print('Repo: ', repo_dict['html_url'])
print('Description: ', repo_dict['description'])
其实像这样已经得到结果了
200 响应成功!
总仓库数: 1768021
top 30
Name: awesome-python
Owner: vinta
Stars: 35236
Repo: https://github.com/vinta/awesome-python
Description: A curated list of awesome Python frameworks, libraries, software and resources
Name: httpie
Owner: jakubroztocil
Stars: 30149
Repo: https://github.com/jakubroztocil/httpie
Description: Modern command line HTTP client – user-friendly curl alternative with intuitive UI, JSON support, syntax highlighting, wget-like downloads, extensions, etc. https://httpie.org
Name: thefuck
Owner: nvbn
Stars: 28535
Repo: https://github.com/nvbn/thefuck
Description: Magnificent app which corrects your previous console command.
...
可视化一下当然会更加直观。
pygal可视化数据
代码不是很难,有一个plot_dict
比较关键,这是鼠标放在条形图上时,会显示出来的数据,键基本上都是固定写法,xlink
里面时仓库地址,只要点击,浏览器就会新开一个标签跳转到该页面了!
import requests
import pygal
from pygal.style import LightColorizedStyle, LightenStyle
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
response = requests.get(url)
# 200为响应成功
print(response.status_code, '响应成功!')
response_dict = response.json()
total_repo = response_dict['total_count']
repo_list = response_dict['items']
print('总仓库数: ', total_repo)
print('top', len(repo_list))
names, plot_dicts = [], []
for repo_dict in repo_list:
names.append(repo_dict['name'])
# 加上str强转,因为我遇到了'NoneType' object is not subscriptable (: 说明里面有个没有此项, 是NoneType
plot_dict = {
'value' : repo_dict['stargazers_count'],
# 有些描述很长很长,选最前一部分
'label' : str(repo_dict['description'])[:200]+'...',
'xlink' : repo_dict['html_url']
}
plot_dicts.append(plot_dict)
# 改变默认主题颜色,偏蓝色
my_style = LightenStyle('#333366', base_style=LightColorizedStyle)
# 配置
my_config = pygal.Config()
# x轴的文字旋转45度
my_config.x_label_rotation = -45
# 隐藏左上角的图例
my_config.show_legend = False
# 标题字体大小
my_config.title_font_size = 30
# 副标签,包括x轴和y轴大部分
my_config.label_font_size = 20
# 主标签是y轴某数倍数,相当于一个特殊的刻度,让关键数据点更醒目
my_config.major_label_font_size = 24
# 限制字符为15个,超出的以...显示
my_config.truncate_label = 15
# 不显示y参考虚线
my_config.show_y_guides = False
# 图表宽度
my_config.width = 1000
# 第一个参数可以传配置
chart = pygal.Bar(my_config, style=my_style)
chart.title = 'Most-Starred Python Projects on GitHub'
# x轴的数据
chart.x_labels = names
# 加入y轴的数据,无需title设置为空,注意这里传入的字典,
# 其中的键--value也就是y轴的坐标值了
chart.add('', plot_dicts)
chart.render_to_file('most_stars_python_repo.svg')
看下图,chrome浏览器里显示效果。总感觉config里面有些设置没有起到作用, x、y轴的标签还是那么小orz...不过plot_dict
里面的三个数据都显示出来了,点击即可跳转。
好了,就折腾这么多吧,这个库也不是特别大众的...
by @sunhaiyu
2017.6.22
pygal的简单使用的更多相关文章
- Python3 数据可视化之matplotlib、Pygal、requests
matplotlib的学习和使用 matplotlib的安装 pip3 install matplotlib 简单的折线图 import matplotlib.pyplot as plt #绘制简单的 ...
- Python制作折线图
利用python的第三方包Pygal制作简单的折线图. 申明:本文仅供学习交流使用.源码大部分来自<python编程从入门到实践>:如有侵权,请联系我删除. 1 #!usr/bin/env ...
- SNMPv3/pygal制图/smtplib发邮件
SNMPv3 SNMPv3在路由器端的配置 这个我都没配置过,还得现学现卖这个链接说的是SNMPv3的基本配置 这个链接说的是SNMPv3的view命令,用于管理员可以看到哪些层级的内容 1) 配置 ...
- pygal and matplotlib(again)
之前项目有用过pygal做chart图, 写代码很容易,几行代码就很做出一个看上去还不错的chart, 缺点是: 要调的再美观很难, Web上的交互效果较差. 在web上做可视化还是推荐采用Echar ...
- flask框架+pygal+sqlit3搭建图形化业务数据分析平台
一. 前言 先说下主要的框架和主要的图形库的特点:(个人见解) Django:python开发的一个重量级的web框架,集成了MVC和ORM等技术,设计之初是为了使开发复杂的.数据库驱动的网站变得简单 ...
- Python常用的库简单介绍一下
Python常用的库简单介绍一下fuzzywuzzy ,字符串模糊匹配. esmre ,正则表达式的加速器. colorama 主要用来给文本添加各种颜色,并且非常简单易用. Prettytable ...
- Python数据可视化---pygal模块
目录 pygal模块 安装pygal模块 pygal模块介绍 柱状图 单列柱状图 堆叠柱状图 横向柱状图 折线图 简单折线图 纵向折线图 堆叠折线图 饼状图 简单饼状图 多级饼状图 圆环图 半圆图 雷 ...
- Python Pygal 模块安装和使用你get了吗?
Pygal 是另一个简单易用的数据图库,它以面向对象的方式来创建各种数据图,而且使用 Pygal 可以非常方便地生成各种格式的数据图,包括 PNG.SVG 等.使用 Pygal 也可以生成 XML e ...
- 【造轮子】打造一个简单的万能Excel读写工具
大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...
随机推荐
- css3动画小案例
今天与大家来分享一下我做的css3动画案例. 在展示我的案例之前先给大家说说实现这个案例所需要的一些属性. transform 属性允许我们对元素进行旋转.缩放.移动或倾斜. 通过 CSS3 2D转换 ...
- Spring定时任务实例
一.Quartz介绍 在企业应用中,我们经常会碰到时间任务调度的需求,比如每天凌晨生成前天报表,每小时生成一次汇总数据等等.Quartz是出了名的任务调度框架,它可以与J2SE和J2EE应用程序相结合 ...
- IE11中navigator.userAgent的变化
在原来判断浏览器是否是ie时,我们可以根据navigator.userAgent中时候有MSIE,但是IE11进行变革,userAgent中不在包含MSIE字段, 在实际项目中,入到类似的在控制台报错 ...
- RandomAccessFile乱码问题
转自:http://www.cnblogs.com/xudong-bupt/archive/2013/04/20/3028980.html Thanks Java对文件的读.写随机访问,Ran ...
- ajax提交到后台是中文乱码
运行程序时遇到用ajax的url中传递数据,后台用request.getParamet()时出现中文乱码 $.ajax({ type: "POST", url: g_sBasePa ...
- H3CNE实验:通过Console端口本地访问H3C设备
连接好Console线后,将交换机开机,在SecureCRT上会显示如下信息: Starting...... RAMLine.....OK System is booting............. ...
- 极客圈(一)树莓派3B协同Python打造个性化天气闹钟
人生苦短,我用Python~ 一直想自己折腾些极客的东西出来,供自己使用或者是供他人使用.一则可能对自己的生活是一种帮助,二则是对自己技能的提高,三则显得高大上,一直努力,一直提高,一直Happy!~ ...
- [CF161D]Distance in Tree-树状dp
Problem Distance in tree 题目大意 给出一棵树,求这棵树上有多少个最短距离为k的点对. Solution 这个题目可以用点分治来做,然而我到现在还是没有学会点分治,所以只好用树 ...
- MySql单表最大8000W+ 之数据库遇瓶颈记
前言 昨晚救火到两三点,早上七点多醒来,朦胧中醒来发现电脑还开着,赶紧爬起来看昨晚执行的SQL命令结果.由于昨晚升级了阿里云的RDS,等了将近两个小时 还在 升降级中,早上阿里云那边回复升级过程中出现 ...
- webgl自学笔记——光照
在Webgl中我们使用顶点着色器和片元着色器来为我们的场景创建光照模型.着色器允许我们使用数学模型来控制如何照亮我们的场景. 最好有线性代数的相关知识. 本章中: 光源.法线.材料 光照和着色的区别 ...