Python——定义一个类来进行北京污染物的可视化(pyecharts绘制折线图、饼图、北京地图)

目录

作业基本要求

数据来源

其他要求

一、源代码

二、可视化展示

1.绘制随时间变化曲线图

2.绘制某一时点下污染物占比

 3.绘制北京地图下的各个检测站污染情况

​编辑 4.分析变量之间的相关性(污染物含量与气象状态)


作业基本要求

数据来源

经济管理中通常有大量的数据以csv等结构化格式存在,如本次作业要用的空气质量数据。数据见在线平台,格式说明如https://archive.ics.uci.edu/ml/datasets/Beijing+Multi-Site+Air-Quality+Data

其他要求

1. 至少实现一个数据分析类,以提供数据的读取及基本的时间(如某区域某类型污染物随时间的变化)和空间分析(某时间点或时间段北京空气质量的空间分布态势)方法。

2. 至少实现一个数据可视化类,以提供上述时空分析结果的可视化,如以曲线、饼、地图等形式对结果进行呈现。

3. 如果数据中包含空值等异常值(可人工注入错误数据以测试异常抛出与处理的逻辑),在进行数据分析以及可视化前需要检查数据。因此需要实现NotNumError类,继承ValueError,并加入新属性region, year,month,day,hour,pollutant,对数据进行检测,若取到的一列数据中包含空值等明显错误,则抛出该异常,并提供异常信息。在此基础上,利用try except捕获该异常,打印异常信息,并对应位置的数据进行适当的填充。

4. (附加)污染物含量与气象状态本身是否有相关性?请丰富数据分析类和数据可视化类,增加关于这些相关性探索的方法。

5. (附加)思考不同区域时间变化的趋势及差异的管理意义。

一、源代码

from pyecharts import Line,Pie,Map
import pandas as pd
import numpy as np
from seaborn.matrix import heatmap  #绘制热力图
import matplotlib.pyplot as plt
from pyecharts.charts import Geo
from pyecharts import options as opts
from pyecharts.globals import GeoType
import pyecharts

class Data_ana:
    '''这是一个提高数据读取操作的类'''
    def __init__(self,path_list,station_list):
        '''初始化传入一个路径列表和检测站列表'''
        self.path_list = path_list
        self.station_list = station_list
    def read_csv(self,station):
        '''这是一个根据传入的监测站,读入对应csv文件的函数'''
        i = self.station_list.index(station)
        df = pd.read_csv(self.path_list[i],header=0)
        return df
    def time_ana(self,station,pollutant):
        pass
    def area_ana(self,time):
        pass
    
class Data_plt:
    '''数据可视化类'''
    def __init__(self,path_list,station_list):
        '''初始化,把路径和检查站名称列表传入'''
        self.path_list = path_list
        self.station_list = station_list

    def station_pollutant_graph(self,station,pollutant):
        '''绘制出某一个检测站某种污染物随时间的变化'''
        A = Data_ana(self.path_list, self.station_list)
        df = A.read_csv(station)
        data_array = np.array(df)
        data_list =data_array.tolist() #将dataframe转化为list
        
        time_list = []
        num_list = []
        row_name = ['No','year','month','day','hour','PM2.5','PM10','SO2','NO2','CO','O3','TEMP','PRES','DEWP','RAIN','wd','WSPM','station']
        index1 = row_name.index(pollutant) 
        for i in data_list[1:1000]:
            time_list.append(str(i[1])+'.'+str(i[2])+'.'+str(i[3])+'.'+str(i[4])) #对应的时间
            num_list.append(i[index1]) #对应的值
        
        line = Line("在{},{}随着时间的变化折线图".format(station,pollutant))
        line.add(station, time_list, num_list, mark_point=["average"])
        line.render()
    
    def time_station_pie(self,time_str,station):
        '''绘制在某一时间下,某一检测站不同污染物的占比的饼图'''
        A = Data_ana(self.path_list, self.station_list)
        df = A.read_csv(station)
        data_array = np.array(df)
        data_list =data_array.tolist()  #将dataframe转化为list
        
        time = time_str.split('.')
        year = int(time[0]);month = int(time[1]);day = int(time[2]);hour = int(time[3])
        
        i = 0;flag = 1
        while i < len(data_list) and flag == 1:
            if year == data_list[i][1] and month == data_list[i][2] and day == data_list[i][3] and hour == data_list[i][4]:
                num_list = data_list[i][5:11]
                flag = 0
            i = i + 1
        pollutants = ['PM2.5','PM10','SO2','NO2','CO','O3']
        pie = Pie('{}{}'.format(station,time_str))
        pie.add("", pollutants, num_list, is_label_show=True)
        pie.render()
        
    def bj_time_pollutant_map(self,time_str,pollutant):
        '''传入时间和污染物,在北京地图上绘制不同检查站的数据'''
        values = []
        A = Data_ana(self.path_list, self.station_list)  #将A实例化为第一个类
        row_name = ['No','year','month','day','hour','PM2.5','PM10','SO2','NO2','CO','O3','TEMP','PRES','DEWP','RAIN','wd','WSPM','station']
        index1 = row_name.index(pollutant) #找出我们选定的污染物在数据中的列数
        time = time_str.split('.')
        year = int(time[0]);month = int(time[1]);day = int(time[2]);hour = int(time[3]) #将我们传入的数据分割
        for station in self.station_list:  #对每个监测站进行遍历
            df = A.read_csv(station)
            data_array = np.array(df)
            data_list =data_array.tolist() #由dataframe转化为list
            i = 0;flag = 1
            while i < len(data_list) and flag == 1:
                #对比时间
                if year == data_list[i][1] and month == data_list[i][2] and day == data_list[i][3] and hour == data_list[i][4]:
                    value = data_list[i][index1]
                    values.append(value)
                    flag = 0
                i = i + 1
        
        #下面开始地图绘制环节
        city = '北京'
        g = pyecharts.charts.Geo()
        g.add_schema(maptype=city)
        # 定义坐标对应的名称,添加到坐标库中 add_coordinate(name, 经度, 纬度)
        g.add_coordinate('奥体中心', 116.401665, 39.985069)
        g.add_coordinate('昌平', 116.23128, 40.22077)
        g.add_coordinate('定陵', 116.10098901489258, 40.36113569243784)
        g.add_coordinate('东四', 116.42371240356445, 39.92600162086124)
        g.add_coordinate('官园', 116.35916772583008, 39.93495273529134)
        g.add_coordinate('古城', 116.197319, 39.908829)
        g.add_coordinate('怀柔', 116.64601388671875, 40.32397764738031)
        g.add_coordinate('农展馆', 116.46147790649414, 39.94127046425559)
        g.add_coordinate('顺义', 116.66146341064453, 40.15966193736629)
        g.add_coordinate('天坛', 116.41189990551759, 39.88038235336456)
        g.add_coordinate('万柳', 116.28929076702882, 39.972465789671865)
        g.add_coordinate('万寿西宫', 116.35602412731934, 39.878933304535224)
        data_pair = []
        #通过一个循环,得到一个数据对
        for i in range(len(values)):
            data_pair.append((self.station_list[i],values[i]))
        # 将数据添加到地图上
        g.add('', data_pair, type_=GeoType.EFFECT_SCATTER, symbol_size=7)
        # 设置样式
        g.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        # 自定义分段 color 可以用取色器取色
        pieces = [
            {'max': 1, 'label': '0以下', 'color': '#50A3BA'},
            {'min': 1, 'max': 10, 'label': '1-10', 'color': '#3700A4'},
            {'min': 10, 'max': 20, 'label': '10-20', 'color': '#81AE9F'},
            {'min': 20, 'max': 30, 'label': '20-30', 'color': '#E2C568'},
            {'min': 30, 'max': 50, 'label': '30-50', 'color': '#FCF84D'},
            {'min': 50, 'max': 100, 'label': '50-100', 'color': '#DD0200'},
            {'min': 100, 'max': 200, 'label': '100-200', 'color': '#DD675E'},
            {'min': 200, 'label': '200以上', 'color': '#D94E5D'}  # 有下限无上限
        ]
        #  is_piecewise 是否自定义分段, 变为true 才能生效
        g.set_global_opts(
            visualmap_opts=opts.VisualMapOpts(is_piecewise=True, pieces=pieces),
            title_opts=opts.TitleOpts(title="{},{}各地{}检测".format(time_str,city,pollutant)),
        )
        g.render()
  
    def station_heatmap(self,station):
        '''这是一个绘制不同变量相关系数热力图的函数'''
        A = Data_ana(self.path_list, self.station_list)
        df = A.read_csv(station)
        df1 = df.iloc[:,1:]
        heatmap(df1.corr(),annot = True,fmt = ".2f",vmax = 1,square = True, xticklabels = False,cmap = "Reds",annot_kws={'size':7})

class NotNumError(Exception):   #NotNumError类,用来检验是否有空值
    def __init__(self,station_list,pollutants,station,df):
        '''初始化函数'''
        self.station_list = station_list
        self.pollutants = pollutants
        self.station = station
        self.df = df
    def check(self):
        '''检查函数,传入一个dataframe'''
        data_array = np.array(self.df)
        data_list =data_array.tolist() #由dataframe转化为list
        flag = 0
        for row in data_list:
            for index in range(len(row)):
                if row[index] == None:
                    self.message = f'在{self.station}监测站,第{row[0]}行,第{index+1}个数据为空'
                    flag = 1
        if flag == 0:
            self.message  = '没有错误'
    def __str__(self):
        '''抛出异常信息的初始化函数'''
        return self.message  #抛出异常实例
    

def main():
    path_list = ["D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Aotizhongxin_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Changping_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Dingling_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Dongsi_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Guanyuan_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Gucheng_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Huairou_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Nongzhanguan_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Shunyi_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Tiantan_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Wanliu_20130301-20170228.csv",
                 "D:\学习文件\大三上\现代程序设计\第七次作业\PRSA_Data_20130301-20170228\PRSA_Data_Wanshouxigong_20130301-20170228.csv"]
    row_name = ['No','year','month','day','hour','PM2.5','PM10','SO2','NO2','CO','O3','TEMP','PRES','DEWP','RAIN','wd','WSPM','station']
    station_list = ['奥体中心','昌平','定陵','东四','官园','古城','怀柔','农展馆','顺义','天坛','万柳','万寿西宫']
    PLT = Data_plt(path_list, station_list)
    #PLT.station_heatmap('奥体中心')
    PLT.station_pollutant_graph('奥体中心','PM2.5')
    #PLT.bj_time_pollutant_map('2015.10.20.12','NO2')
    PLT.time_station_pie('2015.9.6.20','古城')


main()

二、可视化展示

1.绘制随时间变化曲线图

 

2.绘制某一时点下污染物占比

 3.绘制北京地图下的各个检测站污染情况

 

 4.分析变量之间的相关性(污染物含量与气象状态)

 

在RAIN(雨天),WSPM9(风速)大的情况下,污染情况都比较小

'PM2.5','PM10','SO2','NO2','CO’这五类污染物之间相关性比较强,尤其是PM2.5和PM10

O3比较独立

好的,根据您的要求,我会为您提供相应的代码。首先,我们需要将数据读取到 pandas 的 DataFrame 中: ```python import pandas as pd class DataAnalysis: def __init__(self, file_path): self.data = pd.read_csv(file_path) ``` 接着,我们可以实现基本的时间分析方法,比如查询某区域某污染物随时间的变化: ```python class DataAnalysis: def __init__(self, file_path): self.data = pd.read_csv(file_path) def pollution_over_time(self, region, pollutant): region_data = self.data[self.data['station'] == region] pollutant_data = region_data[['date', pollutant]] return pollutant_data.groupby('date').mean() ``` 我们也可以实现空间分析方法,比如查询某时间点或时间段北京空气质量的空间分布态势: ```python class DataAnalysis: def __init__(self, file_path): self.data = pd.read_csv(file_path) def spatial_analysis(self, date=None, start_date=None, end_date=None): if date: data = self.data[self.data['date'] == date] elif start_date and end_date: data = self.data[(self.data['date'] >= start_date) & (self.data['date'] <= end_date)] else: raise ValueError('Please provide either a date or a start and end date') return data.groupby('station').mean() ``` 接下来,我们可以实现数据可视化,以便对上述时空分析结果进行可视化: ```python import matplotlib.pyplot as plt import folium class DataVisualization: def __init__(self, data_analysis): self.data_analysis = data_analysis def visualize_pollution_over_time(self, region, pollutant): pollutant_data = self.data_analysis.pollution_over_time(region, pollutant) plt.plot(pollutant_data.index, pollutant_data[pollutant]) plt.xlabel('Date') plt.ylabel(pollutant) plt.title('{} pollution over time in {}'.format(pollutant, region)) plt.show() def visualize_spatial_analysis(self, date=None, start_date=None, end_date=None): station_data = self.data_analysis.spatial_analysis(date, start_date, end_date) map = folium.Map(location=[39.9, 116.3], zoom_start=10) for index, row in station_data.iterrows(): marker = folium.Marker(location=[row['latitude'], row['longitude']], tooltip=row.name, popup='{}: {:.2f}'.format(row.name, row['PM2.5'])) marker.add_to(map) return map ``` 最后,我们可以利用 apply 方法对数据进行异常值的处理,并进行探索污染物含量与气象状态之间的相关性: ```python class DataAnalysis: def __init__(self, file_path): self.data = pd.read_csv(file_path) def pollution_over_time(self, region, pollutant): region_data = self.data[self.data['station'] == region] pollutant_data = region_data[['date', pollutant]] return pollutant_data.groupby('date').mean() def spatial_analysis(self, date=None, start_date=None, end_date=None): if date: data = self.data[self.data['date'] == date] elif start_date and end_date: data = self.data[(self.data['date'] >= start_date) & (self.data['date'] <= end_date)] else: raise ValueError('Please provide either a date or a start and end date') return data.groupby('station').mean() def handle_outliers(self): self.data[['PM2.5', 'PM10', 'SO2', 'NO2', 'CO', 'O3']] = self.data[['PM2.5', 'PM10', 'SO2', 'NO2', 'CO', 'O3']].apply(lambda x: x.clip(lower=x.quantile(0.01), upper=x.quantile(0.99))) def explore_correlations(self): corr_matrix = self.data[['PM2.5', 'PM10', 'SO2', 'NO2', 'CO', 'O3', 'temperature', 'pressure', 'humidity', 'wind_direction', 'wind_speed/kph']].corr() return corr_matrix ``` 以上就是根据您的要求实现的数据分析和数据可视化的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值