使用python中的numpy+matplotlib进行数据可视化练习(新手向)

前言

题目来源为2019年本科大数据应用大赛网络选拔赛试题,总共三个可视化题目,全部使用numpy和matplotlib完成可视化(数据文件在文章末尾,数据示例如下,字段含义分别为:时间,PM2.5指数,城市,地区)
所用数据

一、PM2.5的平均数(条形图)

在这里插入图片描述

解答思路

1.首先导入numpy和matplotlib.pyplot,使用pyplot编程。
2.使用numpy中的loadtxt导入文件。
3.提取出数组中所需的字段,并求出平均值。
4.使用matplotlib画出柱状图。

详细代码及思路

导入库文件,并且将中文设置为黑体,避免中文乱码问题

#导入mumpy和pyplot
import numpy as np
import matplotlib.pyplot as plt
#解决可视化过程中的中文乱码问题
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

使用loadtxt函数导入文件,第一个参数不能直接使用文件名,要将文件通过utf-8的格式打开,设置分隔符为’,’ ,字段格式为np.str

#导入文件
txt = np.loadtxt(open('airpm25.txt',encoding = 'utf-8'),delimiter = ',',dtype = np.str)
txt

在这里插入图片描述
定义画图所需的横纵坐标

#定义横纵坐标
locations = ['合肥','黄山','芜湖']
average = []

接下来对数据进行清洗,提取出有用数据。通过循环遍历三个地点,其中涉及到numpy中的where函数和切片操作。
1.首先通过where函数提取出txt数组中第三列的元素为’合肥’的索引(第一次循环)
2.然后通过所得索引提取出这些数组中第二列我们需要的pm2.5的指数,设置指数类型为int64,构造数组,通过mean函数求得平均值。
3.最后依次追加到average列表中,得到纵坐标列表。
4.画图并得出结果
注:保存文件时,我使用最初plt.savefig('test1.png)'得到的是空白文件,在网上找到的都是那两个方法,都没用,最后才找到这个方法plt.savefig('test1.png', bbox_inches="tight")才可以保存。

#遍历三个地区
for location in locations:
    index = np.where(txt[...,2] == location)                  #使用where方法分别提取出第三个字段为合肥...的索引
    ave = np.array(txt[index][...,1],dtype=np.int64).mean()   #将合肥...字段的pm2.5的值构成一个数组,并在最后取平均值
    average.append(ave)                                        #追加到纵坐标的数组中
    
plt.bar(locations,average)               #创建条形图,横纵坐标为location,average
plt.title('合肥、黄山、芜湖的PM2.5指数') #设置标题
plt.xlabel('城市名称')                  
plt.ylabel('PM2.5的平均值')             #设置横纵坐标注释
plt.savefig('test1.png', bbox_inches="tight")
plt.show()

在这里插入图片描述

二、pm2.5的平均值随时间的变化(折线图)

在这里插入图片描述

解答思路

1.导入文件和库
2.对不同地点,分别进行按月份的求平均值,求出所需的随时间变化的pm2.5数据
3.使用matplotlib画出折线图。

详细代码及思路

导入库和文件

#导入mumpy和pyplot
import numpy as np
import matplotlib.pyplot as plt
#解决可视化过程中的中文乱码问题
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

locations = ['合肥','黄山','芜湖']
average = []

对数据清洗,提取。
1.依旧利用循环提取出各个地点的数据索引,使用unique函数对第一列数据(时间)进行去重,提取出所有时间变量。
2.分别在每个地区的数据中找到所有时间中每个月的数据,并根据索引,进行分组求平均值,最后追加到average列表中。
ave = np.array(txt[index][n][...,1],dtype = np.int32).mean()
这句中的txt[index]中的[index]一定不能省略,因为上一句中使用where函数得到的索引是在txt[index]中的索引,而不是txt中的索引,所以,如使用txt[n][…,1],就会得到错误的索引。

3.在每个地点循环结束的时候都画一次折线图,并把average列表清空。
4.设置折线图的属性(由于最新的matplotlib会自动将多个折线的颜色区分,所以可以不用设置颜色。)

average = []#测试所用
fig = plt.figure()#OO编程,创建一个画布
for location in locations:
    index = np.where(txt[...,2] == location)
    time = np.unique(txt[...,0])
    for x in time:
        n = np.where(txt[index][...,0] == x)
        ave = np.array(txt[index][n][...,1],dtype = np.int32).mean()
        average.append(ave)
    plt.plot(time,average)
    average = []

plt.xlabel('日期')
plt.ylabel('PM2.5的平均值')
plt.title('合肥、黄山、芜湖各城市随时间的pm2.5平均值')
plt.legend(locations)#显示图例,按照地点循环的顺序
fig.autofmt_xdate()#OO编程,使x轴坐标显示自适应
plt.savefig('test1.png', bbox_inches="tight")
plt.show()

在这里插入图片描述

三、合肥市高新区和庐阳区的pm2.5的值(柱线混合图)

在这里插入图片描述

详细代码及思路(思路大致与上述两题相同)

导入库和文件

#导入mumpy和pyplot
import numpy as np
import matplotlib.pyplot as plt
#解决可视化过程中的中文乱码问题
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

#导入文件
txt = np.loadtxt(open('airpm25.txt',encoding = 'utf-8'),delimiter = ',',dtype = np.str)

对数据进行清洗,提取
1.由于数据类型教少,所以我选择了分开讨论两个区的数据,而不用循环。
2.首先提取合肥市数据的索引,然后对时间数据进行去重。
3.从合肥市数据中提取出庐阳区和高新区的数据索引。之所以不直接从最后一个字段提取两个区的索引,是为了防止重名。
4.分别提取两个区的PM2.5数据。
5.分别创建柱状图和折线图,设置图的属性和图例,设置自适应x轴坐标显示。

fig = plt.figure()
hefei = np.where(txt[...,2]=='合肥')
time = np.unique(txt[...,0])
luyang = np.where(txt[hefei][...,3] == '庐阳区')
gaoxin = np.where(txt[hefei][...,3] == '高新区')
result_1 = np.array(txt[hefei][luyang][...,1],dtype=np.int64)
result_2 = np.array(txt[hefei][gaoxin][...,1],dtype=np.int64)
print(result_1)
print(result_2)

plt.bar(time,result_1,label='庐阳区')
plt.plot(time,result_2,label='高新区',color = 'r')
plt.xlabel('日期')
plt.ylabel('PM2.5的平均值')
plt.title('合肥市的高新区和庐阳区的pm2.5的值')
plt.legend()
fig.autofmt_xdate()
plt.savefig('test1.png', bbox_inches="tight")
plt.show()

在这里插入图片描述

结语

这些都是初级的可视化例子,我在网上找了很多地方,感觉很少有数据可视化的题目,所以就写了一个发出来,希望能帮到一些和我一样刚入门的小白。

数据链接:链接:https://pan.baidu.com/s/1oKtIgl2GnIzkR973doTNcQ
提取码:o53z

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值