Python学习之路日志—利用matplotlib开发数据可视化项目(6)

今天,我将继续昨天对世界人口地图的制作:

4.2.5 在世界地图上呈现数字数据:

为练习在地图上呈现数字数据,我们来创建一幅地图,显示三个北美国家的人口数量:

在这里插入图片描述

import pygal_maps_world.maps

wm = pygal_maps_world.maps.World()
wm.title = 'Population of Countries in North America'
wm.add('North America', {'ca':34126000, 'us':309349000, 'mx':113423000})

wm.render_to_file('na_population.svg')

首先,创建了一个Worldmap 实例并设置了标题。接下来,使用了方法add() ,但这次通过第二个实参传递了一个字典而不是列表(见第5行)。这个字典将两个字母的Pygal国别码作为键,将人口数量作为值。Pygal根据这些数字自动给不同国家着以深浅不一的颜色:

在这里插入图片描述

4.2.6 绘制完整的世界人口地图:

要呈现其他国家的人口数量,需要将前面处理的数据转换为Pygal要求的字典格式:键为两个字母的国别码,值为人口数量。为此,在world_population.py中添加如下代码:
在这里插入图片描述

import json

import pygal_maps_world.maps

from country_codes import get_country_code

# Load data into a list
filename = 'population_data.json'
with open(filename) as f:
	pop_data = json.load(f)

# Print the population of each country in 2010a
cc_populations = {}
for pop_dict in pop_data:
	if pop_dict['Year'] == '2010':
		country = pop_dict['Country Name']
		population = int(float(pop_dict['Value']))
		code = get_country_code(country)
		if code:
			cc_populations[code] = population

wm = pygal_maps_world.maps.World()
wm.title = 'World population in 2010, by Country'
wm.add('2010', cc_populations)

wm.render_to_file('world_population.svg')

我们首先导入了pygal_maps_world.maps 。在第13行处,我们创建了一个空字典,用于以Pygal要求的格式存储国别码和人口数量。在第20行处,如果返回了国别码,就将国别码和人口数量分别作为键和值填充字典cc_populations 。我们还删除了所有的print 语句。 在第22行处,我们创建了一个实例,并设置其title 属性。在第24行处,我们调用了add() ,并向它传递由国别码和人口数量组成的字典。下图显示了生成的地图:

在这里插入图片描述

4.2.7 根据人口数量将国家分组:

印度和中国的人口比其他国家多得多,但在当前的地图中,它们的颜色与其他国家差别较小。中国和印度的人口都超过了10亿,接下来人口最多的国家是美国,但只有大约3亿。 下面不将所有国家都作为一个编组,而是根据人口数量分成三组——少于1000万的、介于1000万和10亿之间的以及超过10亿的:

在这里插入图片描述

import json

import pygal_maps_world.maps

from country_codes import get_country_code

# Load data into a list
filename = 'population_data.json'
with open(filename) as f:
	pop_data = json.load(f)

# Print the population of each country in 2010a
cc_populations = {}
for pop_dict in pop_data:
	if pop_dict['Year'] == '2010':
		country = pop_dict['Country Name']
		population = int(float(pop_dict['Value']))
		code = get_country_code(country)
		if code:
			cc_populations[code] = population

 # All countries are divided into three groups according to the population size
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for cc, pop in cc_populations.items():
	if pop < 10000000:
		cc_pops_1[cc] = pop
	elif pop < 1000000000:
		cc_pops_2[cc] = pop
	else:
		cc_pops_3[cc] = pop

# see how many countries each group contains
print(len(cc_pops_1), len(cc_pops_2), len(cc_pops_3))

wm = pygal_maps_world.maps.World()
wm.title = 'World population in 2010, by Country'
wm.add('0-10m', cc_pops_1)
wm.add('10m-1bn',  cc_pops_2)
wm.add('>1bn', cc_pops_3)

wm.render_to_file('world_population.svg')

为将国家分组,我们创建了三个空字典(见第23行)。接下来,遍历cc_populations ,检查每个国家的人口数量(见第24行)。if-elif-else 代码块将每个国别码-人口数量对加入到合适的字典(cc_pops_1cc_pops_2cc_pops_3 )中。 在第33行处,我们打印这些字典的长度,以获悉每个分组的规模。绘制地图时,我们将全部三个分组都添加到wm中。

上述输出表明,人口少于1000万的国家有85个,人口介于1000万和10亿之间的国家有69个,还有两个国家比较特殊,其人口都超过了10亿。这样的分组看起来足够了,让地图包含丰富的信息。下图显示了生成的地图:

在这里插入图片描述

现在使用了三种不同的颜色,让我们能够看出人口数量上的差别。在每组中,各个国家都按人口从少到多着以从浅到深的颜色。

4.2.8 使用Pygal设置地图的样式:

在这个地图中,根据人口将国家分组虽然很有效,但默认的颜色设置很难看。例如,在这里,Pygal选择了鲜艳的粉色和绿色基色。下面使用Pygal样式设置指令来调整颜色。 我们也让Pygal使用一种基色,但将指定该基色,并让三个分组的颜色差别更大:

在这里插入图片描述

import json

import pygal_maps_world.maps

from pygal.style import RotateStyle
from country_codes import get_country_code

# Load data into a list
filename = 'population_data.json'
with open(filename) as f:
	pop_data = json.load(f)

# Print the population of each country in 2010a
cc_populations = {}
for pop_dict in pop_data:
	if pop_dict['Year'] == '2010':
		country = pop_dict['Country Name']
		population = int(float(pop_dict['Value']))
		code = get_country_code(country)
		if code:
			cc_populations[code] = population

 # All countries are divided into three groups according to the population size
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for cc, pop in cc_populations.items():
	if pop < 10000000:
		cc_pops_1[cc] = pop
	elif pop < 1000000000:
		cc_pops_2[cc] = pop
	else:
		cc_pops_3[cc] = pop

# see how many countries each group contains
print(len(cc_pops_1), len(cc_pops_2), len(cc_pops_3))

wm_style = RotateStyle('#336699')
wm = pygal_maps_world.maps.World(style=wm_style)
wm.title = 'World population in 2010, by Country'
wm.add('0-10m', cc_pops_1)
wm.add('10m-1bn',  cc_pops_2)
wm.add('>1bn', cc_pops_3)

wm.render_to_file('world_population.svg')

Pygal样式存储在模块style 中,我们从这个模块中导入了样式RotateStyle (见第5行)。创建这个类的实例时,需要提供一个实参——十六进制的RGB颜色(见第36行);Pygal将根据指定的颜色为每组选择颜色。这里使用的颜色值(#336699)混合了少量的红色(33)、多一些的绿色(66)和更多一些的蓝色(99),它为RotateStyle 提供了一种淡紫色基色。 RotateStyle 返回一个样式对象,我们将其存储在wm_style 中。为使用这个样式对象,我们在创建wm 实例时以关键字实参的方式传递它(见第37行)。前面的样式设置让地图的颜色更一致,也更容易区分不同的编组。更新后的地图如下图所示:

在这里插入图片描述

4.2.9 加亮颜色主题:

Pygal通常默认使用较暗的颜色主题。为方便印刷,我使用LightColorizedStyle 加亮了地图的颜色。这个类修改整个图表的主题,包括背景色、标签以及各个国家的颜色:

在这里插入图片描述

import json

import pygal_maps_world.maps

from pygal.style import LightColorizedStyle as LCS, RotateStyle as RS
from country_codes import get_country_code

# Load data into a list
filename = 'population_data.json'
with open(filename) as f:
	pop_data = json.load(f)

# Print the population of each country in 2010a
cc_populations = {}
for pop_dict in pop_data:
	if pop_dict['Year'] == '2010':
		country = pop_dict['Country Name']
		population = int(float(pop_dict['Value']))
		code = get_country_code(country)
		if code:
			cc_populations[code] = population

 # All countries are divided into three groups according to the population size
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for cc, pop in cc_populations.items():
	if pop < 10000000:
		cc_pops_1[cc] = pop
	elif pop < 1000000000:
		cc_pops_2[cc] = pop
	else:
		cc_pops_3[cc] = pop

# see how many countries each group contains
print(len(cc_pops_1), len(cc_pops_2), len(cc_pops_3))

wm_style = RS('#336699', base_style=LCS)
wm = pygal_maps_world.maps.World(style=wm_style)
wm.title = 'World population in 2010, by Country'
wm.add('0-10m', cc_pops_1)
wm.add('10m-1bn',  cc_pops_2)
wm.add('>1bn', cc_pops_3)

wm.render_to_file('world_population.svg')

通过使用几个样式设置指令,就能很好地控制图表和地图的外观。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值