侧边栏壁纸
博主头像
liveJQ博主等级

沒有乐趣,何来开始

  • 累计撰写 146 篇文章
  • 累计创建 60 个标签
  • 累计收到 2 条评论

Python可视化数据

liveJQ
2019-03-01 / 0 评论 / 0 点赞 / 623 阅读 / 4,509 字 / 正在检测是否收录...
广告 广告

json数据类型

world_population.json,这个文件包含全球大部分国家1960~2016年的人口数据。Open Knowledge Foundation提供了大量可
以免费使用的数据集。

[{
"Country Code": "ARB", 
"Country Name": "Arab World", 
"Value": 92490932.0, 
"Year": 1960
},
{
"Country Code": "ARB", 
"Country Name": "Arab World", 
"Value": 95044497.0, 
"Year": 1961
},...
}]

可使用python标准模块json来载入此类型文件。

csv数据类型

这是阿拉斯加锡特卡2014年1月5日的天气数据,其中包含当天的最高气温和最低气温,还有众多其他数据。CSV文件对人来说阅读起来比较麻烦,但程序可轻松地提取并处理其
中的值,这有助于加快数据分析过程。

	AKST,Max TemperatureF,Mean TemperatureF,Min TemperatureF,Max Dew PointF,MeanDew PointF,Min DewpointF,Max Humidity, Mean Humidity, Min Humidity, Max Sea Level PressureIn, Mean Sea Level PressureIn, Min Sea Level PressureIn, Max VisibilityMiles, Mean VisibilityMiles, Min VisibilityMiles, Max Wind SpeedMPH, Mean Wind SpeedMPH, Max Gust SpeedMPH,PrecipitationIn, CloudCover, Events, WindDirDegrees
2014-1-1,46,42,37,40,38,36,97,86,76,29.95,29.77,29.57,10,8,2,25,14,36,0.69,8,Rain,138
2014-1-2,41,38,35,38,35,32,97,89,76,30.09,29.90,29.81,10,9,4,14,7,22,0.34,8,Rain,92

可使用python标准模块csv(Comma-Separated-Values逗号分隔值)来载入此类型文件。

Matplotlib模块

20190302_matplotlib.png

import csv
from matplotlib import pyplot as plt
from datetime import datetime

filename = 'death_valley_2014.csv'
with open(filename) as f:#默认为'r'读取
    reader = csv.reader(f)
    # 作用:每次读取下一行,在此为第一行(字段名),之后阅读器则从第二行开始继续读取CSV文件
    header_row = next(reader)
    
    dates, highs , lows= [], [], []
    #for index, column_header in enumerate(header_row):
    #这是测试代码,测试日期、最高温、最低温在哪一列
        #print(index, column_header)
    for row in reader:
        try:
            date = datetime.strptime(row[0], "%Y-%m-%d")
            high = int(row[1])
            low = int(row[3])
        except ValueError:
            print(date, 'missing date')
        else:
            dates.append(date)
            highs.append(high)
            lows.append(low)            
# 初始化画板的像素和大小
fig = plt.figure(dpi=128, figsize=(10, 6))
# x、y、颜色、透明度(x未指定则默认从0开始)
plt.plot(dates, highs, c='red', alpha=0.5)
plt.plot(dates, lows, c='blue', alpha=0.5)
# x、y1、y2、透明度
plt.fill_between(dates, highs, lows, alpha=0.1)

plt.title("Daily high and low temperatures - 2014\nDeath Valley, July 2014", fontsize=24)
# ''为空,不指定x轴的标签
plt.xlabel('', fontsize=5)

#日期自动适应x轴(就是斜向下45度,比较宽松)
fig.autofmt_xdate()
plt.ylabel('Temperature (F)', fontsize=14)
# which一共3个参数[‘major’ , ‘minor’ ,‘both’] 
# 默认是major表示主刻度,后面分布为次刻度及主次刻度都显示
# axis='both'表示应用x和y两个轴	
plt.tick_params(axis='both', which='major', labelsize=16)

plt.show()

20190302_high_low_demo.png

pygal模块

20190302_pygal.png

import json
	
import pygal
from pygal_maps_world.i18n import COUNTRIES
from pygal.maps.world import World
from pygal.style import RotateStyle, LightColorizedStyle

filename = 'world_population.json'

def get_country_code(country_name):
    """通过国家名返回国别码(两位)"""
    for code, name in COUNTRIES.items():
        if name == country_name:
            return code
    return None

# 设置板块风格,为板块提供基色
wm_style = RotateStyle('#336699', base_style=LightColorizedStyle)
worldmap_chart = World(style=wm_style)
worldmap_chart.title = 'Population Distribution'
cc_populations = {}

# 解析16年各国的人口数据
with open(filename) as f:
    pop_data = json.load(f)
    for pop_dict in pop_data:
        if pop_dict['Year'] == 2016:
            country_name = pop_dict['Country Name']
            population = int(float(pop_dict['Value']))
            code = get_country_code(country_name)
            if code:
                cc_populations[code] = population

# 分三类数据,每个国别码对应一个人口数据
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for country_code, pop in cc_populations.items():
    if pop < 10000000:
        cc_pops_1[country_code] = pop
    elif pop < 1000000000:
        cc_pops_2[country_code] = pop
    else:
        cc_pops_3[country_code] = pop
        
worldmap_chart.add('<10b', cc_pops_1)
worldmap_chart.add('10b-1bn', cc_pops_2)
worldmap_chart.add('>1bn', cc_pops_3)
worldmap_chart.render_to_file('worldmap_demo2.svg')
print("Rendering Successfully!")

20190302_world_population.png

这里唯一需要注意的一点就是获取国别码,pygal 2.0之后COUNTRIES已经不在pygal模块里面了,需要pip install pygal_maps_world,然后再from pygal_maps_world.i18n import COUNTRIES调用;使用世界地图也是得先安装上述模块,然后from pygal.maps.world import World才有效(应该是调用了上面模块里的某些东西吧)

time与datetime

由于上述中出现了对时间的一些用法,在这里也顺便提一下。

关于日期时间的格式,看下表。

格式指令 含义
%Y 带世纪的四位年份,如2017
%y 后两位年份,如17表示2017
%m 月份,从01到12
%B 完整的月份,如November
%b 月份的简写,如Nov
%d 一个月中的第几天,如从01到31(如果有的话)
%j 一年中的第几天
%w 一周中的第几天
%A 完整的周几,如Monday
%a 简写的周几,如Mon
%H 24小时制的小时00-23
%h 12小时制的小时01-12
%M 分,00-59
%S 秒,00-59
%p AM或者PM

import time,datetime
	
#将字符串时间格式化为时间
timeStr = "2019-2-27 12:52:00"
time1 = datetime.datetime.strptime(timeStr, "%Y-%m-%d %H:%M:%S")
print(time1)
print(type(time1))
#输出
#2019-02-27 12:52:00
#<class 'datetime.datetime'>


#将时间格式化为字符串
time4 = time.strftime("%Y-%m-%d %H:%M:%S", time3)
print(time4)
print(type(time4))
#输出
#2019-02-27 12:52:00
#<class 'str'>


#将时间转化为1970至今的毫秒数
time2 = time.mktime(time1.timetuple())
print(time2)
#输出:
#1551243120.0


#将毫秒数结构化为本地时间
time3 = time.localtime(1551243120)
print("\n", time3)
#输出
#time.struct_time(tm_year=2019, tm_mon=2, #tm_mday=27, tm_hour=12, tm_min=52, tm_sec=0, #tm_wday=2, tm_yday=58, tm_isdst=0)
0

评论区