实验内容:根据给定数据绘制欧洲国家某一日的疫情情况。
eu_country_names = ['Austria','Belgium','Bulgaria' , 'Croatia', 'Cyprus',
'Czechia','Denmark', 'Estonia','Finland','France','Germany',
'Greece', 'Hungary','Ireland', 'ltaly','Latvia', 'Lithuania',
'Luxembourg', 'Malta', 'Netherlands', 'Poland','Portugal',
'Romania', 'Slovakia','Slovenia','Spain','Sweden','United Kingdom']
numbers=[173,313,54,11,34,56,26,78,333,237,179,113,67,80,340,15,213,24,31,64,66,36,38,215,307,69,36,87] #虚拟的
一、获取地理文件位置
from cartopy.io import shapereader
#获取文件路径
filename=shapereader.natural_earth(resolution='110m', #默认的是110m的physical信息
category='cultural',
name='admin_0_countries')#指定读cultural的国家信息
二、创建地理文件的阅读器对象
reader=shapereader.Reader(filename)
for record in reader.records(): #多个国家的信息逐一遍历
print(record)
三、绘制世界地图绘图区
import matplotlib.pyplot as plt
from cartopy.crs import PlateCarree
#创建绘图区
fig=plt.figure(figsize=(10,8),dpi=500)
ax=fig.add_subplot(projection=PlateCarree(central_longitude=0))#创建绘图区
plt.show()
四、绘制世界地图边界线
#添加各个国家边界线
for record in reader.records(): #多个国家的信息逐一遍历
ax.add_geometries([record.geometry],PlateCarree(),facecolor='green',edgecolor='black')
plt.show()
五、根据疫情数据给世界地图染色
from matplotlib.cm import YlOrRd #把一个0~1的颜色转换为RGBA的元组
from matplotlib.colors import rgb2hex #把一个RGBA的元组信息转换成一个16进制的颜色
max_value=200
for i, record in enumerate(reader.records()):
rgba=YlOrRd(i/max_value)
color=rgb2hex(rgba)
ax.add_geometries([record.geometry],PlateCarree(),facecolor=color,edgecolor='black')
plt.show()
六、绘制颜色条
from matplotlib.colors import rgb2hex,Normalize #把一个RGBA的元组信息转换成一个16进制的颜色
from matplotlib.colorbar import ColorbarBase
#添加绘图区
cax=fig.add_axes([0.95,0.25,0.02,0.5])
plt.show()
#创建归一化转换器对象
norm=Normalize(vmin=0,vmax=max_value)#把vmin,vmax数据转换到0~1之间
#创建颜色条并添加到绘图区
ColorbarBase(cax,cmap=YlOrRd,norm=norm,label='colorbar')
七、局部放大欧洲地区
extent=[-20,50,30,70] #经纬度范围
ax.set_extent(extent) #聚焦到欧洲区域
八、补充国家信息
eu_country_names = ['Austria','Belgium','Bulgaria' , 'Croatia', 'Cyprus',
'Czechia','Denmark', 'Estonia','Finland','France','Germany',
'Greece', 'Hungary','Ireland', 'ltaly','Latvia', 'Lithuania',
'Luxembourg', 'Malta', 'Netherlands', 'Poland','Portugal',
'Romania', 'Slovakia','Slovenia','Spain','Sweden','United Kingdom']
numbers=[173,313,54,11,34,56,26,78,333,237,179,113,67,80,340,15,213,24,31,64,66,36,38,215,307,69,36,87] #虚拟的
eu_countires=[]
for record in reader.records(): #多个国家的信息逐一遍历
if record.attributes['NAME'] in eu_country_names:
print(record.attributes['NAME'])
eu_countires.append(record)
j=eu_country_names.index(record.attributes['NAME'])
rgba=YlOrRd(numbers[j]/max_value)
color=rgb2hex(rgba)
print(numbers[j],rgba,color)
ax.add_geometries([record.geometry],PlateCarree(),facecolor=color,edgecolor='black')
但是没有出任何结果,地图也是空白。
于是我单独把下面一段代码拿出来进行测试
eu_country_names = ['Austria', 'Belgium', 'Bulgaria', 'Croatia', 'Cyprus',
'Czechia', 'Denmark', 'Estonia', 'Finland', 'France', 'Germany',
'Greece', 'Hungary', 'Ireland', 'ltaly', 'Latvia', 'Lithuania',
'Luxembourg', 'Malta', 'Netherlands', 'Poland', 'Portugal',
'Romania', 'Slovakia', 'Slovenia', 'Spain', 'Sweden', 'United Kingdom']
for record in reader.records(): #多个国家的信息逐一遍历
if record.attributes['NAME'] in eu_country_names:
print(record.attributes['NAME'])
发现也是空白,什么信息也没有。当我单独执行下面代码时,发现是有信息的。
那为什么会遍历不出来呢?于是我又开始测试,此时我发现遍历的信息里包含了大量特殊字符。
既然已经知道了原因,那么接下来就好办了。把代码改进过后,如下
for record in reader.records(): #多个国家的信息逐一遍历
if record.attributes['NAME'].strip('\x00') in eu_country_names:
print(record.attributes['NAME'].strip('\x00'))
eu_countires.append(record)
j=eu_country_names.index(record.attributes['NAME'].strip('\x00'))
rgba=YlOrRd(numbers[j]/max_value)
color=rgb2hex(rgba)
print(numbers[j],rgba,color)
ax.add_geometries([record.geometry],PlateCarree(),facecolor=color,edgecolor='black')
大功告成!
完整代码如下
from cartopy.io import shapereader
import matplotlib.pyplot as plt
from cartopy.crs import PlateCarree
from matplotlib.cm import YlOrRd #把一个0~1的颜色转换为RGBA的元组
from matplotlib.colors import rgb2hex,Normalize #把一个RGBA的元组信息转换成一个16进制的颜色
from matplotlib.colorbar import ColorbarBase
#获取文件路径
filename=shapereader.natural_earth(resolution='110m', #默认的是110m的physical信息
category='cultural',
name='admin_0_countries')#指定读cultural的国家信息
#创建地理文件阅读器对象
reader=shapereader.Reader(filename)
#创建绘图区
fig=plt.figure(figsize=(10,8),dpi=500)
ax=fig.add_subplot(projection=PlateCarree(central_longitude=0))#创建绘图区
eu_country_names = ['Austria','Belgium','Bulgaria' , 'Croatia', 'Cyprus',
'Czechia','Denmark', 'Estonia','Finland','France','Germany',
'Greece', 'Hungary','Ireland', 'ltaly','Latvia', 'Lithuania',
'Luxembourg', 'Malta', 'Netherlands', 'Poland','Portugal',
'Romania', 'Slovakia','Slovenia','Spain','Sweden','United Kingdom']
numbers=[173,313,54,11,34,56,26,78,333,237,179,113,67,80,340,15,213,24,31,64,66,36,38,215,307,69,36,87]
eu_countires=[]
discounnum={}
max_value=max(numbers)
#添加各个国家边界线
for record in reader.records(): #多个国家的信息逐一遍历
# ax.add_geometries([record.geometry],PlateCarree(),facecolor='green',edgecolor='black')
if record.attributes['NAME'].strip('\x00') in eu_country_names:
print(record.attributes['NAME'].strip('\x00'))
eu_countires.append(record)
j=eu_country_names.index(record.attributes['NAME'].strip('\x00'))
rgba=YlOrRd(numbers[j]/max_value)
color=rgb2hex(rgba)
print(numbers[j],rgba,color)
ax.add_geometries([record.geometry],PlateCarree(),facecolor=color,edgecolor='black')
#添加绘图区
cax=fig.add_axes([0.95,0.25,0.02,0.5])
#创建归一化转换器对象
norm=Normalize(vmin=0,vmax=max_value)#把vmin,vmax数据转换到0~1之间
#创建颜色条并添加到绘图区
ColorbarBase(cax,cmap=YlOrRd,norm=norm,label='colorbar')
extent=[-20,50,30,70] #经纬度范围
ax.set_extent(extent) #聚焦到欧洲区域
plt.show()