【Python学习笔记】【matplotlib】(十四)数据可视化:下载数据,气温图表CSV、交易收盘价走势图JSON

下载数据

绘制气温图表:CSV文件格式

CSV格式存储:逗号分隔的一系列值。
下载天气数据:https://www.wunderground.com/history

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

# 从文件中获取信息
filename = 'sitka_weather_07-2014.csv' # 一个包含天气数据的csv文件
with open(filename) as f:
    reader = csv.reader(f) # 创建一个与文件相关的阅读器对象
    header_row = next(reader) # 返回文件中的下一行。第一行:文件头

    # 打印文件头
    # print(header_row)
    for index, column_header in enumerate(header_row): # 获取每个元素的索引及其值
        print(index, column_header)

    # 获取文件中的日期(0)和最高温(1)和最低温(3)
    highs = []
    dates = []
    lows = []
    for row in reader:
        try:
            date_format = "%Y-%m-%d" # 格式控制
            date = datetime.strptime(row[0], date_format)
            high = int(row[1]) # 字符->整形。matolptlib能读取的类型
            low = int(row[3])
        except ValueError: # 避免数据缺失,读取‘ ’
            print(date, 'missing!')
        else:
            dates.append(date)
            highs.append(high)
            lows.append(low)

# 根据数据绘制图形
fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red')
plt.plot(dates, lows, c='green')
plt.fill_between(dates, highs, lows, facecolor='green', alpha=0.1) # 图表区域着色,alpha值(0-1)表示透明度
plt.title("Daliy temperatures", fontsize=24)
plt.xlabel("Days", fontsize=18)
fig.autofmt_xdate() # 绘制斜的日期标签,避免重叠
plt.ylabel("F", fontsize=18)
plt.tick_params(axis='both', which='major', labelsize=14)

plt.show()

在这里插入图片描述

制作交易收盘价走势图:JSON格式

下载JSON文件的方式

  1. 直接从网址下载https://raw.githubusercontent.com/muxuezi/btc/master/btc_close_2017.json
  2. 使用标准库模块urllib中的函数urlopen
from __future__ import (absolute_import, division, print_function, unicode_literals)
from urllib.request import urlopen  # python3
import json

# 向GitHub服务器发送请求
json_url = "https://raw.githubusercontent.com/muxuezi/btc/master/btc_close_2017.json"
response = urlopen(json_url)

# 读取数据
req = response.read()

# 将数据写入文件
with open('btc_close_2017_urllib.json', 'wb') as f:
    f.write(req)

# 加载json格式
file_urllib = json.loads(req.decode('utf8')) # 转换成Python能处理的格式
print(file_urllib)

报错了两次:urllib.error.URLError: <urlopen error [Errno 11004] getaddrinfo failed>
[11001] 第六行单引号改成双引号 参考
[11004] 电脑配置的DNS不能使用了,修改DNS地址为114.114.114.114参考
3. 使用标准库模块requests

import requests

# 向GitHub服务器发送请求
json_url = 'https://raw.githubusercontent.com/muxuezi/btc/master/btc_close_2017.json'
req = requests.get(json_url)

# 将数据写入文件
with open('btc_close_2017_request.json', 'w') as f:
    f.write(req.text)  # text属性可以直接读取文件数据,返回字符串格式
file_requests = req.json() # 转换文件的数据为Python列表

分析数据

收盘价对数变化
import json
import pygal
import math

# 加载数据到列表
filename = 'btc_close_2017_request.json'
with open(filename) as f:
    btc_data = json.load(f) # 一个列表,每个元素都是一个包含五个键的字典

# 创建5个列表。存储信息
dates = []
months = []
weeks = []
weekdays = []
closes = []

# 打印每一天的信息。原本键和值格式都为字符串,需要转换为数值
for btc_dict in btc_data:
    date = btc_dict['date']
    month = int(btc_dict['month'])
    week = int(btc_dict['week'])
    weekday = btc_dict['weekday']
    close = int(float(btc_dict['close']))  # 包含小数的字符串不能直接转换为数值
    # print("{} is month {} week {}, {}, the close price is {} RMB".format(date, month, week, weekday, close))

    dates.append(date)
    months.append(month)
    weeks.append(week)
    weekdays.append(weekday)
    closes.append(close)

# 绘制收盘价对数变换折线图
line_chart = pygal.Line(x_label_rotation=20, show_minor_x_labels=False)  # 倾斜角度,不完全显示x轴标签
line_chart.title = '收盘价对数变换折线'
line_chart.x_labels = dates
N = 20  # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]  # 切片操作。[开头:结束:步长]
closes_log = [math.log10(x) for x in closes] # 做对数变换,消除非线性的趋势
line_chart.add('log收盘价', closes_log)
line_chart.render_to_file('收盘价对数变换折线图.svg') # 文件保存

在这里插入图片描述

收盘价均值
import json
import pygal
from itertools import groupby # 分组操作函数

# 加载数据到列表
filename = 'btc_close_2017_request.json'
with open(filename) as f:
    btc_data = json.load(f) # 一个列表,每个元素都是一个包含五个键的字典

# 创建5个列表。存储信息
dates = []
months = []
weeks = []
weekdays = []
closes = []

# 打印每一天的信息。原本键和值格式都为字符串,需要转换为数值
for btc_dict in btc_data:
    date = btc_dict['date']
    month = int(btc_dict['month'])
    week = int(btc_dict['week'])
    weekday = btc_dict['weekday']
    close = int(float(btc_dict['close']))  # 包含小数的字符串不能直接转换为数值
    # print("{} is month {} week {}, {}, the close price is {} RMB".format(date, month, week, weekday, close))

    dates.append(date)
    months.append(month)
    weeks.append(week)
    weekdays.append(weekday)
    closes.append(close)

# 绘制收盘价均值表
def draw_line(x_data, y_data, title, y_legend):
    # 计算收盘价均值
    xy_map = [] # 存放均值
    # 将x、y轴数据合并、排序,再用函数grouphy分组
    for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0]):  # 2
        y_list = [v for _, v in y]
        xy_map.append([x, sum(y_list) / len(y_list)])  # 3

    x_unique, y_mean = [*zip(*xy_map)]  # 将合并的x、y轴数据分离

    # 制作折线图
    line_chart = pygal.Line()
    line_chart.title = title
    line_chart.x_labels = x_unique
    line_chart.add(y_legend, y_mean)
    line_chart.render_to_file(title + '.svg')
    return line_chart

idx_month = dates.index('2017-12-01') # 查找列表中元素位置
line_chart_month = draw_line(
    months[:idx_month], closes[:idx_month], '收盘价月日均值', '月日均值')
line_chart_month

在这里插入图片描述
有一句代码真是难懂:for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0])
理解:x_date,y_date分别是一个列表,将这个列表打包成一个元素,然后根据x_date列表的第一个元素将这个包分组。返回的x为这个包的键,y为这个包的值。
zip()函数,接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
groupby函数,按照键值(key)或者分组变量将数据分组。

python学习:zip函数
python3中的groupby函数用法

收盘价数据仪表盘

数据仪表盘(dashboard)就是把生成的SVG文件整合到一个页面。
SVG是矢量图,文件可以任意缩放不失真。

with open('收盘价Dashboard.html', 'w', encoding='utf8') as html_file:
    html_file.write(
        '<html><head><title>收盘价Dashboard</title><meta charset="utf-8"></head><body>\n')
    for svg in ['收盘价折线图.svg', '收盘价对数变换折线图.svg', '收盘价月日均值.svg']:
        html_file.write(
            '    <object type="image/svg+xml" data="{0}" height=500></object>\n'.format(svg))  # 1
    html_file.write('</body></html>')

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值