首页 > 编程语言 >Python入门笔记(三)

Python入门笔记(三)

时间:2022-12-08 12:38:57浏览次数:43  
标签:plt 入门 Python self chart 笔记 dict btc line


文章目录

  • ​​第十二章 异常处理​​
  • ​​12.1 常见异常​​
  • ​​12.2 处理异常:try-- except​​
  • ​​12.3 创建异常类型:raise语句​​
  • ​​12.4 断言:assert​​
  • ​​12.5 存储数据:json.dump()和json.load()​​
  • ​​第十三章 测试代码​​
  • ​​13.1 测试函数​​
  • ​​13.2 测试类​​
  • ​​第十四章. matplotlib​​
  • ​​14.1 折线图​​
  • ​​14.2 散点图​​
  • ​​14.3 保存图表​​
  • ​​14.4 绘制随机漫步图​​
  • ​​14.5 使用Pygal模拟掷骰子​​
  • ​​第十五章. 下载数据​​
  • ​​15.1 csv文件​​
  • ​​15.2 json文件​​
  • ​​第十六章. 使用API​​
  • ​​16.1 requests​​


第十二章 异常处理

程序将停止,并显示一个traceback。

12.1 常见异常

AssertionError

断言语句(assert)失败

AttributeError

尝试访问未知的对象属性

EOFError

用户输入文件末尾标志EOF(Ctrl+d)

FloatingPointError

浮点计算错误

GeneratorExit

generator.close()方法被调用的时候

ImportError

导入模块失败的时候

IndexError

索引超出序列的范围

KeyError

字典中查找一个不存在的关键字

KeyboardInterrupt

用户输入中断键(Ctrl+c)

MemoryError

内存溢出(可通过删除对象释放内存)

NameError

尝试访问一个不存在的变量

NotImplementedError

尚未实现的方法

OSError

操作系统产生的异常(例如打开一个不存在的文件)

OverflowError

数值运算超出最大限制

ReferenceError

弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象

RuntimeError

一般的运行时错误

StopIteration

迭代器没有更多的值

SyntaxError

Python的语法错误

IndentationError

缩进错误

TabError

Tab和空格混合使用

SystemError

Python编译器系统错误

SystemExit

Python编译器进程被关闭

TypeError

不同类型间的无效操作

UnboundLocalError

访问一个未初始化的本地变量(NameError的子类)

UnicodeError

Unicode相关的错误(ValueError的子类)

UnicodeEncodeError

Unicode编码时的错误(UnicodeError的子类)

UnicodeDecodeError

Unicode解码时的错误(UnicodeError的子类)

UnicodeTranslateError

Unicode转换时的错误(UnicodeError的子类)

ValueError

传入无效的参数

ZeroDivisionError

除数为零

TypeError:类型错误
不同类型间的操作出现的错误

1 + '1'
TypeError: unsupported operand type(s) for +: 'int' and 'str'

例2

age = input('请输入你的年龄')
if age >= 18:
print('成年人...')

Python入门笔记(三)_ide


SyntaxError:语法错误

print'zdb'
SyntaxError: invalid syntax

IndexError: 索引错误
索引超出序列的范围

my_list = [1, 2, 3]   # 这里是0到2的索引
my_list[3]
IndexError: list index out of range

NameError :尝试访问一个不存在的变量

fishc
NameError: name 'fishc' is not defined

AssertionError :断言语句(assert)失败

my_list = ['zdb']
assert len(my_list) > 0
my_list.pop() #列表只有一个元素,删除了就为0
assert len(my_list) > 0
Traceback (most recent call last):
File "C:/Users/zdb/PycharmProjects/untitled/temp.py", line 4, in <module>
assert len(my_list) > 0
AssertionError

AttributeError :尝试访问未知的对象属性

my_list = ['zdb']
assert len(my_list) > 0
my_list.fishc #fishc不知道是什么,访问失败
AttributeError: 'list' object has no attribute 'fishc'

KeyError 字典中查找一个不存在的关键字

my_dict = {'one':1, 'two':2, 'three':3}
my_dict['one']
my_dict['four']
KeyError: 'four'

不报错解决方法: get()

my_dict = {'one':1, 'two':2, 'three':3}
print(my_dict.get('four'))
None

ZeroDivisionError :除数为零

5 / 0
ZeroDivisionError: division by zero


12.2 处理异常:try-- except

例:代码出错,程序终止

f = open('我为什么是一个文件.txt')    #没有这个文件
print(f.read()) #输出文件里面的内容
f.close() #关闭文件
FileNotFoundError: [Errno 2] No such file or directory: '我为什么是一个文件.txt'

为了解决上述代码终止运行的问题,这里进行异常处理
try—except

try:
f = open('我为什么是一个文件.txt')
print(f.read())
f.close()

except OSError: # 如果上面代码出现这个异常
print('文件出错了')
文件出错了

try–except----except—except…

如果可能出现多个异常,可以使用多个except

Python入门笔记(三)_json_02


例:

Python入门笔记(三)_json_03

try—except ----as —

try:
f = open('我为什么是一个文件.txt')
print(f.read())
f.close()
except OSError as reason: # 出现这个异常,执行下面语句
print('文件出错了\n错误的原因是:' + str(reason))
文件出错了
错误的原因是:[Errno 2] No such file or directory: '我为什么是一个文件.txt'

try:
sum = 1+'1'
except TypeError as reason:
print('类型出错了\n错误的原因是:' + str(reason))
类型出错了
错误的原因是:unsupported operand type(s) for +: 'int' and 'str'

try----except----else—

try:
int('123')
except ValueError as reason:
print('出错了!' + str(raeson)) # 出现valueerror异常输出这个
else:
print('没有任何异常!') #没有异常输出这句
没有任何异常!

try----except----else----finally
finally后面的语句是无论try里面的代码出不出错都会执行的

try:
f = open('data.txt', 'w') #写入的方式打开
for each_line in f:
print(each_line) #输出内容
except OSError as reason:
print('出错了:' + str(reason))
finally: #finally定会执行
f.close()
出错了:not readable

例2

try:
with open('data.txt', 'w') as f: #相当于f=open()
for each_line in f:
print(each_line)
except OSError as reason: #打开一个不存在的文件
print('出错了:' + str(reason))
finally:
f.close()
出错了:not readable


12.3 创建异常类型:raise语句

raise ZeroDivisionError('除数为零的异常')
raise ZeroDivisionError('除数为零的异常')
ZeroDivisionError: 除数为零的异常

def triangle(a, b, c):
if (a+b<=c)|(a+c<=b)|(b+c<=a):
raise Exception('不满足两边之和大于第三边!')
else:
print('是三角形!')

try:
triangle(1,2,3)
except Exception as error:
print('错误:' + str(error))
错误:不满足两边之和大于第三边!


12.4 断言:assert

  • 断言是一个完整性的检查,确保代码没有做什么明显错误的事情。这些完整的检查由assert语句执行。如果检查失败,就会抛出异常。

assert语句包含以下部分:

  • assert关键字
  • 条件(即求值为True或False的表达式)
  • 逗号
  • 当条件为False时显示的字符串
assert 3<4, '正确'
assert 3>4, '错误'

Python入门笔记(三)_json_04


12.5 存储数据:json.dump()和json.load()

  • 模块json让你能够将简单的python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。还可以在python程序之间分享数据,在其它语言之间也能分享。

1、函数json.dump()接受两个参数:要存储的数据、存储数据的文件对象。

import json

numbers = [2, 3, 5, 7, 11, 13]

filename = 'numbers.json'
with open(filename, 'w') as f_obj: #写入的方式打开,用f_obj表示
json.dump(numbers,f_obj) #两个参数,存储的数据,文件对象

Python入门笔记(三)_python_05


2、使用json.load()将这个列表读取到内存中

import json

filename = 'numbers.json'
with open(filename) as f_obj: #写入的方式打开,用f_obj表示
numbers = json.load(f_obj)
print(numbers)

Python入门笔记(三)_json_06



第十三章 测试代码

13.1 测试函数

1、编写name_function.py模块

def get_formatted_name(first, last):
"""生成整洁的姓名"""
full_name = first + ' ' + last
return full_name.title()

2、在names.py中测试

from name_function import get_formatted_name

print("Enter 'q' at any time to quit.")
while True:
first = input("\nPlease give me a first name: ")
if first == 'q':
break
last = input("Please give me a last name: ")
if last == 'q':
break

formatted_name = get_formatted_name(first, last) #创建实例
print("\tNeatly formatted name: " + formatted_name + '.')

3、输出

Enter 'q' at any time to quit.

Please give me a first name: z
Please give me a last name: db
Neatly formatted name: z db.

Please give me a first name: z
Please give me a last name: q

可以发现我们每次修改name_function.py,都要重新运行names.py,然后重新输入姓名,这样太繁琐了。Python标准库中的模块unittest提供了代码测试工具。

(1)可通过的测试
先导入模块unittest以及要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。
1、在test_name_function.py中测试name_function.py里面的get-formatted_name()

#导入unittest模块
import unittest
#导入要测试的模块函数
from name_function import get_formatted_name

#创建NameTestCase类,继承unittest.TestCase父类
class NamesTestCase(unittest.TestCase):
"""测试name_function.py"""

#定义方法
def test_first_last_name(self):
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
#创建实例,存储在formatted_name中
formatted_name = get_formatted_name('janis', 'joplin')
#断言方法,用来核实得到的结果是否和期望的结果一致
#两个参数进行比较
self.assertEqual(formatted_name, "Janis Joplin")

unittest.main()

Python入门笔记(三)_数据_07


这样测试是不是比上面的方法要方便很多

(2)不能通过的测试

1、修改name_function.py,使其包含中间名

Python入门笔记(三)_数据_08


2、运行test_name_function.py,输出

E
======================================================================
ERROR: test_first_last_name (__main__.NamesTestCase)
能够正确地处理像Janis Joplin这样的姓名吗?
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:/Users/zdb/PycharmProjects/untitled/temp.py", line 14, in test_first_last_name
formatted_name = get_formatted_name('janis', 'joplin')
TypeError: get_formatted_name() missing 1 required positional argument: 'last'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)



(3)测试未通过怎么办
测试未通过时,不要修改测试,而应修复导致测试不能通过的代码
1、使中间名变设置成可选的

def get_formatted_name(first, last, middle=''):
"""生成整洁的姓名"""
if middle:
full_name = first + ' ' + middle + ' ' + last
else:
full_name = first + ' ' + last
return full_name.title()

2、运行test_name_function.py,输出

Python入门笔记(三)_数据_09


(4)添加新测试
例:添加一个包含中间名的测试
1、在NamesTestCase类中再添加一个方法:

#导入unittest模块
import unittest
#导入要测试的模块函数
from name_function import get_formatted_name

#创建NameTestCase类,继承unittest.TestCase父类
class NamesTestCase(unittest.TestCase):
"""测试name_function.py"""

#定义方法
def test_first_last_name(self):
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
#创建实例,存储在formatted_name中
formatted_name = get_formatted_name('janis', 'joplin')
#断言方法,用来核实得到的结果是否和期望的结果一致
#两个参数进行比较
self.assertEqual(formatted_name, "Janis Joplin")

def test_first_last_middle_name(self):
"""能够正确地处理像Wolfgang Amadeus Mozart这样的姓名吗?"""
formatted_name = get_formatted_name('wolfgang', 'mozart', 'amadeus')
self.assertEqual(formatted_name, "Wolfgang Amadeus Mozart")

unittest.main()

Python入门笔记(三)_python_10


13.2 测试类

各种断言方法

方法

用途

assertEqual

核实a == b

assertNotEqual

核实a != b

assertTrue(x)

核实x为True

assertFalse(x)

核实x为False

assertIn(item, list)

核实item在list中

assertNotIn(item, list)

核实item不在list中


(1)一个要测试的类
1、创建survey.py

class AnonymousSurvey():
"""收集匿名调查问卷的答案"""

def __init__(self, question):
"""存储一个问题,并为存储答案做准备"""
self.question = question
self.responses = [] #答案设置空列表

def show_question(self):
"""显示调查问卷"""
print(self.question)

def store_response(self, new_response):
"""存储单份调查问卷"""
self.responses.append(new_response)

def show_results(self):
"""显示搜集到的所有问卷"""
print("Survey results:")
for response in self.responses:
print('- ' + response)

2、在language_survey.py中测试

from survey import AnonymousSurvey

#定义一个问题,并创建一个表示调查的AnonymousSurvey对象
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)

#显示问题并存储答案
my_survey.show_question()
print("Enter 'q' at any time to quit.\n")
while True: #一直循环,直到输入q跳出
response = input("Language: ")
if response == 'q':
break
my_survey.store_response(response)

#显示调查结果
print("\nThank youto everyone who participated in the survey!")
my_survey.show_results()

3、输出

What language did you first learn to speak?
Enter 'q' at any time to quit.

Language: English
Language: python
Language: math
Language: q

Thank youto everyone who participated in the survey!
Survey results:
- English
- python
- math



(2)测试AnonymousSurvey类

import unittest      
from survey import AnonymousSurvey #导入要测试的类

class TestAnonymousSurvey(unittest.TestCase): #继承了父类
"""针对AnonymousSurvey类的测试"""

def test_store_single_response(self):
"""测试单个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
my_survey= AnonymousSurvey(question) #创建实例
my_survey.store_response('English')

self.assertIn('English', my_survey.responses)

unittest.main()

Python入门笔记(三)_python_11


测试三个

import unittest
from survey import AnonymousSurvey

class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""

def test_store_single_response(self):
"""测试单个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
my_survey= AnonymousSurvey(question)
my_survey.store_response('English')

self.assertIn('English', my_survey.responses)


def test_store_three_responses(self):
"""测试三个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
responses = ['English', 'python', 'C']
for response in responses:
my_survey.store_response(response)

for response in responses:
self.assertIn(response, my_survey.responses) #核实response在my_survey.responses中

unittest.main()

输出

Python入门笔记(三)_ide_12


(3)方法setUp()
上面每个测试方法都创建了一个AnonymousSurvey实例,并在每个方法中都创建了一个答案。setUp()方法可以让我们只创建这些对象一次,并在每个测试方法中使用它们。

import unittest
from survey import AnonymousSurvey

class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""

def setUp(self):
"""创建一个调查对象和一组答案,供使用的测试方法使用"""
question = "What language did you first learn to speak?"
self.my_survey = AnonymousSurvey(question) #创建一个调查对象
self.responses = ['English', 'python', 'C'] #创建一个答案列表,存储在属性中,有self

def test_store_single_response(self):
"""测试单个答案会被妥善地存储"""
self.my_survey.store_response(self.responses[0])
self.assertIn(self.responses[0], self.my_survey.responses)

def test_store_three_responses(self):
"""测试三个答案会被妥善地存储"""
for response in self.responses:
self.my_survey.store_response(response)

for response in self.responses:
self.assertIn(response, self.my_survey.responses)

unittest.main()

Python入门笔记(三)_ide_12



第十四章. matplotlib

win10安装matplotlib:​​pip install matplotlib​

14.1 折线图

例1:绘制简单的折线
需要导入matplotlib模块里面的pyplot

import matplotlib.pyplot as plt

squares = [1, 4, 9, 16, 25]
plt.plot(squares)
plt.show() # 打开matplotlib查看器,并显示绘制的图形

Python入门笔记(三)_数据_14

例2:修改标签文字和线条粗细
linewidth=5决定线的粗细

import matplotlib.pyplot as plt

squares = [1, 4, 9, 16, 25]
plt.plot(squares, linewidth=5) # linediwth决定了绘制线条的粗细

# 设置图表标题,并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24) # title指明标题
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)

# 设置刻度标记的大小
plt.tick_params(axis='both', labelsize=14) # 设置刻度,刻度字号14
plt.show()

Python入门笔记(三)_数据_15

例3:设置x轴正确刻度,校正图形

import matplotlib.pyplot as plt

input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
plt.plot(input_values, squares, linewidth=5) # linediwth决定了绘制线条的粗细

# 设置图表标题,并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24) # title指明标题
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)

# 设置刻度标记的大小
plt.tick_params(axis='both', labelsize=14) # 设置刻度,刻度字号14
plt.show()

可见前后两图x轴不同了

Python入门笔记(三)_python_16

14.2 散点图

例1:画一个点

import matplotlib.pyplot as plt

plt.scatter(2, 4)
plt.show()

Python入门笔记(三)_ide_17

例2:设置刻度坐标

import matplotlib.pyplot as plt

plt.scatter(2, 4, s=200) # s为尺寸

# 设置图表标题并给坐标轴加上标签
plt.title("Square Number", fontsize=24)
plt.xlabel("Value", fontsize=24)
plt.ylabel("Square of Value", fontsize=24)

# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)

plt.show()

Python入门笔记(三)_ide_18

例3:绘制一系列点

import matplotlib.pyplot as plt

x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]

plt.scatter(x_values, y_values, s=100) # s为尺寸

# 设置图表标题并给坐标轴加上标签
plt.title("Square Number", fontsize=24)
plt.xlabel("Value", fontsize=24)
plt.ylabel("Square of Value", fontsize=24)

# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)

plt.show()

Python入门笔记(三)_python_19

例4:绘制1000个点

import matplotlib.pyplot as plt

x_values = list(range(1, 1001))
y_values = [x**2 for x in x_values]

plt.scatter(x_values, y_values, s=40) # s为尺寸

# 设置图表标题并给坐标轴加上标签
plt.title("Square Number", fontsize=24)
plt.xlabel("Value", fontsize=24)
plt.ylabel("Square of Value", fontsize=24)

# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)

# 设置每个坐标轴的取值范围
plt.axis([0, 1100, 0, 1100000])

plt.show()

Python入门笔记(三)_json_20

例5:删除数据点的轮廓
绘制的点默认为蓝色点和黑色轮廓;但绘制多个点时,黑色轮廓可能粘连在一起,这里可以删除轮廓。

plt.scatter(x_values, y_values, edgecolor='none', s=40)

注意:2.0.2版本的matplotlib, edgecolor默认为’none’,所以这里根本不需要这句话

例6:自定义颜色
可以使用RGB颜色模式自定义颜色,要指定自定义颜色,可传递参数c,并设置为一个元组,其中包含三个0~1之间的小数值,分别为红,绿,蓝分量。
如下,显示为深蓝色。

plt.scatter(x_values, y_values, c=(0, 0, 0.8), edgecolor='none', s=40)

Python入门笔记(三)_数据_21


例:使用颜色映射,根据y值的不同,设置不同程度的颜色

import matplotlib.pyplot as plt

x_values = list(range(1, 1001))
y_values = [x**2 for x in x_values]

plt.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, edgecolors='none', s=40)

# 设置图表标题并给坐标轴加上标签
plt.title("Square Number", fontsize=24)
plt.xlabel("Value", fontsize=24)
plt.ylabel("Square of Value", fontsize=24)

# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)

# 设置每个坐标轴的取值范围
plt.axis([0, 1100, 0, 1100000])

plt.show()

Python入门笔记(三)_ide_22

14.3 保存图表

可将plt.show()的调用替换为plt.savefig()的调用

plt.savefig('squares_plot.png', bbox_inches='tight')

第一个实参指定要与什么样的文件名保存图表,存储在.py文件的当前目录中
第二个实参指定将图表多余的空白区域裁剪掉

14.4 绘制随机漫步图

from random import choice
import matplotlib.pyplot as plt

class RandomWalk():
"""一个生成随机漫步数据的类"""

def __init__(self, num_points=5000): # 5000个点
"""初始化随机漫步的属性"""
self.num_points = num_points

# 所有随机漫步都始于(0,0)
self.x_values = [0]
self.y_values = [0]

def fill_walk(self):
"""计算随机漫步包含的所有点"""
while len(self.x_values) < self.num_points: # 不断漫步,直到列表达到指定的长度
# 决定前进方向以及沿这个方向前进的距离
x_direction = choice([1, -1]) # x方向,1为右,-1为左
x_distance = choice([0, 1, 2, 3, 4]) # 距离
x_step = x_direction * x_distance # 带方向的距离

y_direction = choice([1, -1])
y_distance = choice([0, 1, 2, 3, 4])
y_step = y_direction * y_distance

# 拒绝原地踏步
if x_step == 0 and y_step == 0:
continue

# 计算下一个点的x和y值
next_x = self.x_values[-1] + x_step # 最后的一个值生成最新的值
next_y = self.y_values[-1] + y_step

self.x_values.append(next_x)
self.y_values.append(next_y)


# 创建实例,并将其包含的点都绘制出来
rw = RandomWalk()
rw.fill_walk()
plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()

Python入门笔记(三)_json_23


例2:绘制多次随机漫步

只需要修改实例化那里,RandomWalk的类不变

# 只要程序处于活动状态,并将其包含的点都绘制出来
while True:
# 创建一个RandomWalk实例,并将其的点都绘制出来
rw = RandomWalk()
rw.fill_walk()
plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()

keep_running = input("是否绘制下幅图(y/n):")
if keep_running == 'n':
break

例3:给点着色
颜色由浅入深

# 只要程序处于活动状态,并将其包含的点都绘制出来
while True:
# 创建一个RandomWalk实例,并将其的点都绘制出来
rw = RandomWalk()
rw.fill_walk()

point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, c=point_numbers,
cmap=plt.cm.Blues, edgecolors='none', s=15)
plt.show()

keep_running = input("是否绘制下幅图(y/n):")
if keep_running == 'n':
break

Python入门笔记(三)_数据_24


例4:绘制起点和终点

# 只要程序处于活动状态,并将其包含的点都绘制出来
while True:
# 创建一个RandomWalk实例,并将其的点都绘制出来
rw = RandomWalk()
rw.fill_walk()

point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, c=point_numbers,
cmap=plt.cm.Blues, edgecolors='none', s=15)

# 突出起点和终点
plt.scatter(0, 0, c='green', edgecolors='none', s=100) # 起点绿色
plt.scatter(rw.x_values[-1], rw.y_values[-1],
c='red', edgecolors='none', s=100) # 终点红色

plt.show()

keep_running = input("是否绘制下幅图(y/n):")
if keep_running == 'n':
break

Python入门笔记(三)_ide_25

例5:隐藏坐标轴

# 只要程序处于活动状态,并将其包含的点都绘制出来
while True:
# 创建一个RandomWalk实例,并将其的点都绘制出来
rw = RandomWalk()
rw.fill_walk()

point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, c=point_numbers,
cmap=plt.cm.Blues, edgecolors='none', s=15)

# 突出起点和终点
plt.scatter(0, 0, c='green', edgecolors='none', s=100) # 起点绿色
plt.scatter(rw.x_values[-1], rw.y_values[-1],
c='red', edgecolors='none', s=100) # 终点红色

# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)

plt.show()

keep_running = input("是否绘制下幅图(y/n):")
if keep_running == 'n':
break

Python入门笔记(三)_ide_26

例6:增加点到50000,减小点的大小从15到1

# 只要程序处于活动状态,并将其包含的点都绘制出来
while True:
# 创建一个RandomWalk实例,并将其的点都绘制出来
rw = RandomWalk(50000)
rw.fill_walk()

point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, c=point_numbers,
cmap=plt.cm.Blues, edgecolors='none', s=1)

# 突出起点和终点
plt.scatter(0, 0, c='green', edgecolors='none', s=100) # 起点绿色
plt.scatter(rw.x_values[-1], rw.y_values[-1],
c='red', edgecolors='none', s=100) # 终点红色

# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)

plt.show()

keep_running = input("是否绘制下幅图(y/n):")
if keep_running == 'n':
break

Python入门笔记(三)_ide_27

例7:调整尺寸以适合屏幕
最终所有代码如下:

from random import choice
import matplotlib.pyplot as plt


class RandomWalk():
"""一个生成随机漫步数据的类"""

def __init__(self, num_points=5000): # 5000个点
"""初始化随机漫步的属性"""
self.num_points = num_points

# 所有随机漫步都始于(0,0)
self.x_values = [0]
self.y_values = [0]

def fill_walk(self):
"""计算随机漫步包含的所有点"""
while len(self.x_values) < self.num_points: # 不断漫步,直到列表达到指定的长度
# 决定前进方向以及沿这个方向前进的距离
x_direction = choice([1, -1]) # x方向,1为右,-1为左
x_distance = choice([0, 1, 2, 3, 4]) # 距离
x_step = x_direction * x_distance # 带方向的距离

y_direction = choice([1, -1])
y_distance = choice([0, 1, 2, 3, 4])
y_step = y_direction * y_distance

# 拒绝原地踏步
if x_step == 0 and y_step == 0:
continue

# 计算下一个点的x和y值
next_x = self.x_values[-1] + x_step # 最后的一个值生成最新的值
next_y = self.y_values[-1] + y_step

self.x_values.append(next_x)
self.y_values.append(next_y)


# 只要程序处于活动状态,并将其包含的点都绘制出来
while True:
# 创建一个RandomWalk实例,并将其的点都绘制出来
rw = RandomWalk(50000)
rw.fill_walk()

# 6.设置绘图窗口的尺寸
plt.figure(figsize=(10, 6))

point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, c=point_numbers,
cmap=plt.cm.Blues, edgecolors='none', s=1)

# 突出起点和终点
plt.scatter(0, 0, c='green', edgecolors='none', s=100) # 起点绿色
plt.scatter(rw.x_values[-1], rw.y_values[-1],
c='red', edgecolors='none', s=100) # 终点红色

# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)

plt.show()

keep_running = input("是否绘制下幅图(y/n):")
if keep_running == 'n':
break

Python入门笔记(三)_json_28


如果上述代码指定的图表尺寸不合适,可根据需要调整其中的数字。如果你知道自己的系统的分辨率,可使用形参dip向figure()传递该分辨率,以有效的利用可用的屏幕空间

plt.figure(dpi=128, figsize=(10,6))



14.5 使用Pygal模拟掷骰子

pip install pygal==1.7

例1:创建一个掷骰子的类,先来100次

from random import randint

class Die():
"""表示一个骰子的类"""

def __init__(self, num_sides=6):
"""骰子默认为6面"""
self.num_sides = num_sides

def roll(self):
"""返回一个位于1和骰子面数之间的随机值"""
return randint(1, self.num_sides)


# 创建一个D6
die = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(10): # 掷骰子10次
result = die.roll()
results.append(result)

print(results)

结果随机:

[4, 5, 2, 1, 2, 3, 6, 3, 6, 3]

例2:统计结果

# 创建一个D6
die = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000): # 掷骰子1000次
result = die.roll()
results.append(result)

# 分析结果
frequencies = []
for value in range(1, die.num_sides+1): # 遍历1到6
frequency = results.count(value) # 计算出现每个点的次数
frequencies.append(frequency) # 添加到列表中

print(frequencies)
[163, 157, 161, 182, 178, 159]

例3:将结果绘制成直方图

from random import randint
import pygal

class Die():
"""表示一个骰子的类"""

def __init__(self, num_sides=6):
"""骰子默认为6面"""
self.num_sides = num_sides

def roll(self):
"""返回一个位于1和骰子面数之间的随机值"""
return randint(1, self.num_sides)

# 创建一个D6
die = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000): # 掷骰子1000次
result = die.roll()
results.append(result)

# 分析结果
frequencies = []
for value in range(1, die.num_sides+1): # 遍历1到6
frequency = results.count(value) # 计算次数
frequencies.append(frequency) # 添加到列表中
print(frequencies)

# 对结果进行可视化
hist = pygal.Bar() # 创建实例,存储在hist中

hist.title = "一个骰子掷1000次的结果" # 标题
hist.x_labels = ['1', '2', '3', '4', '5', '6'] # x轴标签
hist.x_title = "结果"
hist.y_title = "统计的次数"

hist.add('D6', frequencies) # 传递要添加的值指定的标签
hist.render_to_file('die_visual.svg') # 将图表渲染成.svg文件

Python入门笔记(三)_json_29


要查看生成的直方图,需要用Web浏览器打开,生成的.svg文件在代码所在文件夹下

例4:同时掷两个骰子

from random import randint
import pygal


class Die():
"""表示一个骰子的类"""
def __init__(self, num_sides=6):
"""骰子默认为6面"""
self.num_sides = num_sides

def roll(self):
"""返回一个位于1和骰子面数之间的随机值"""
return randint(1, self.num_sides)


# 创建两个D6骰子
die_1 = Die()
die_2 = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000): # 掷骰子1000次
result = die_1.roll() + die_2.roll() # 两个骰子结果相加
results.append(result)

# 分析结果
frequencies = []
sum_result = die_1.num_sides + die_2.num_sides
for value in range(2, sum_result+1): # 遍历2到12
frequency = results.count(value) # 计算每个点出现的次数
frequencies.append(frequency) # 添加到列表中
print(frequencies)

# 对结果进行可视化
hist = pygal.Bar() # 创建实例,存储在hist中

hist.title = "两个骰子掷1000次的结果" # 标题
hist.x_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] # x轴标签
hist.x_title = "结果"
hist.y_title = "次数统计"

hist.add('D6 + D6', frequencies) # 传递要添加的值指定的标签
hist.render_to_file('die_visual.svg') # 将图表渲染成.svg文件

Python入门笔记(三)_数据_30


例5:同时掷两个面数不同的骰子

from random import randint
import pygal


class Die():
"""表示一个骰子的类"""
def __init__(self, num_sides=6):
"""骰子默认为6面"""
self.num_sides = num_sides

def roll(self):
"""返回一个位于1和骰子面数之间的随机值"""
return randint(1, self.num_sides)


# 创建两个骰子
die_1 = Die() # 6面的骰子
die_2 = Die(10) # 10面的骰子

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(50000):
result = die_1.roll() + die_2.roll() # 两个骰子结果相加
results.append(result)

# 分析结果
frequencies = []
sum_result = die_1.num_sides + die_2.num_sides
for value in range(2, sum_result+1): # 遍历每个可能出现的点数
frequency = results.count(value) # 计算该点数出现的次数
frequencies.append(frequency) # 添加到列表中
print(frequencies)

# 对结果进行可视化
hist = pygal.Bar() # 创建实例,存储在hist中

hist.title = "两个不同面的骰子掷50000次的结果" # 标题
hist.x_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10',
'11', '12', '13', '14', '15', '16'] # x轴标签
hist.x_title = "结果"
hist.y_title = "次数统计"

hist.add('D6 + D10', frequencies) # 传递要添加的值指定的标签
hist.render_to_file('die_visual.svg') # 将图表渲染成.svg文件

Python入门笔记(三)_json_31



第十五章. 下载数据

15.1 csv文件

例1:分析CSV文件头

CSV文件其文件以纯文本的形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。

Python入门笔记(三)_python_32


next()返回文件的下一行

import csv                              # 用于分析CSV文件中的数据行

filename = 'sitka_weather_07-2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行
print(header_row) # 输出显示第一行

数据太多这里剪切一部分

Python入门笔记(三)_数据_33


reader处理文件以逗号分隔第一行数据,并存储在列表中。

例2:打印文件头及其位置
为让文件头数据更容易理解,将列表中的每个文件头及其位置打印出来。
调用enumerate()来获取每个元素的索引及其值

import csv                              # 用于分析CSV文件中的数据行

filename = 'sitka_weather_07-2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行

for index, column_header in enumerate(header_row): # 调用enumerate()来获取每个元素的索引及其值
print(index, column_header)

这里截取一部分图

Python入门笔记(三)_ide_34


例3:提取并读取数据
阅读器对象从其停留的地方继续往下读取CSV文件,每次都自动返回当前所处位置的下一行,由于我们已经读取了文件头行,这个循环将从第二行开始,这行便是数据。

import csv                              # 用于分析CSV文件中的数据行

filename = 'sitka_weather_07-2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行

highs = [] # 空列表
for row in reader: # 遍历每行
high = int(row[1]) # str转int
highs.append(high) # 每行的第1个元素,从第0个开始

print(highs)

Python入门笔记(三)_json_35


Python入门笔记(三)_json_36


例:绘制气温图表

import csv                              # 用于分析CSV文件中的数据行
from matplotlib import pyplot as plt # 画图需要

# 从文件中获取最高气温
filename = 'sitka_weather_07-2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行

highs = [] # 空列表
for row in reader: # 遍历每行
high = int(row[1])
highs.append(high) # 每行的第1个元素,从第0个开始

print(highs)

# 根据数据绘制图像
fig = plt.figure(dpi=128, figsize=(10, 6)) #设置图像大小尺寸
plt.plot(highs, c='red')

# 设置图形的格式
plt.title("Daily high temperatures, July 2014", fontsize=24) # 标题
plt.xlabel('', fontsize=16) # x轴
plt.ylabel("Temperature(F)", fontsize=16) # y轴
plt.tick_params(axis='both', which='major', labelsize=16) # 刻度标记大小

plt.show()

Python入门笔记(三)_数据_37



datetime模块

from datetime import datetime

first_date = datetime.strptime('2014-7-1', '%Y-%m-%d') # 第一个参数传入实参,第二个给设置的格式
print(first_date)
2014-07-01 00:00:00

‘%Y-’ 让python将字符串中第一个连字符前面的部分视为四位的年份;
‘%m-’ 让python将第二个连字符前面的部分视为表示月份的数字;
‘%d’ 让python将字符串的最后一部分视为月份中的一天

方法strptime()可接受各种实参,并根据它们来决定如何解读时期,下表列出这些实参:

实参

含义

%A

星期的名称,如Monday

%B

月份名,如January

%m

用数字表示的月份(01~12)

%d

用数字表示的月份的一天(01~31)

%Y

四位的年份,如2020

%y

两位的年份,如20

%H

24小时制的小时数(00~23)

%I

12小时制的小时数(01~12)

%p

am或pm

%M

分钟数(00~59)

%S

秒数(00~61)


例2:在图表中添加日期

import csv                              # 用于分析CSV文件中的数据行
from matplotlib import pyplot as plt # 画图需要
from datetime import datetime # 将字符串转换为对应日期需要

# 从文件中获取最高气温和日期
filename = 'sitka_weather_07-2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader)

dates, highs = [], [] # 日期,最高温度初始化为空列表
for row in reader: # 遍历每行
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 每行第零个元素
dates.append(current_date) # 添加日期

high = int(row[1]) # 最高温度转化为整型
highs.append(high) # 添加温度

# 根据数据绘制图像
fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red')

# 设置图形的格式
plt.title("Daily high temperatures, July 2014", fontsize=24) # 标题
plt.xlabel('', fontsize=16) # x轴
fig.autofmt_xdate() # 绘制斜的x轴标签
plt.ylabel("Temperature(F)", fontsize=16) # y轴
plt.tick_params(axis='both', which='major', labelsize=16) # 刻度标记大小

plt.show()

Python入门笔记(三)_json_38



例3:添加更多数据,涵盖更长的时间
这里只是换了一个数据更多的文件,改了一个标题

import csv                              # 用于分析CSV文件中的数据行
from matplotlib import pyplot as plt # 画图需要
from datetime import datetime # 将字符串转换为对应日期需要

# 从文件中获取最高气温和日期
filename = 'sitka_weather_2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行

dates, highs = [], [] # 日期,最高温度初始化为空列表
for row in reader: # 遍历每行
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 每行第零个元素
dates.append(current_date) # 添加日期

high = int(row[1]) # 最高温度转化为整型
highs.append(high) # 添加温度

# 根据数据绘制图像
fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red')

# 设置图形的格式
plt.title("Daily high temperatures - 2014", fontsize=24) # 标题
plt.xlabel('', fontsize=16) # x轴
fig.autofmt_xdate() # 绘制斜的x轴标签
plt.ylabel("Temperature(F)", fontsize=16) # y轴
plt.tick_params(axis='both', which='major', labelsize=16) # 刻度标记大小

plt.show()

Python入门笔记(三)_python_39



例4:再绘制一个数据系列
这里多绘制了一个最低温度

import csv                              # 用于分析CSV文件中的数据行
from matplotlib import pyplot as plt # 画图需要
from datetime import datetime # 将字符串转换为对应日期需要

# 从文件中获取最高气温,最低温度和日期
filename = 'sitka_weather_2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行

dates, highs, lows = [], [], [] # 日期,最高温度初始化为空列表
for row in reader: # 遍历每行
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 每行第零个元素
dates.append(current_date) # 添加日期

high = int(row[1]) # 最高温度转化为整型
highs.append(high) # 添加温度

low = int(row[3])
lows.append(low)

# 根据数据绘制图像
fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red')
plt.plot(dates, lows, c='blue')

# 设置图形的格式
plt.title("Daily high and low temperatures - 2014", fontsize=24) # 标题
plt.xlabel('', fontsize=16) # x轴
fig.autofmt_xdate() # 绘制斜的x轴标签
plt.ylabel("Temperature(F)", fontsize=16) # y轴
plt.tick_params(axis='both', which='major', labelsize=16) # 刻度标记大小

plt.show()

Python入门笔记(三)_json_40



例5:给图表区域着色

import csv                              # 用于分析CSV文件中的数据行
from matplotlib import pyplot as plt # 画图需要
from datetime import datetime # 将字符串转换为对应日期需要

# 从文件中获取最高气温,最低温度和日期
filename = 'sitka_weather_2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行

dates, highs, lows = [], [], [] # 日期,最高温度初始化为空列表
for row in reader: # 遍历每行
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 每行第零个元素
dates.append(current_date) # 添加日期

high = int(row[1]) # 最高温度转化为整型
highs.append(high) # 添加温度

low = int(row[3])
lows.append(low)

# 根据数据绘制图像
fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red', alpha=0.5) # alpha指定颜色的透明度,使得红色和蓝色折线看起来更浅
plt.plot(dates, lows, c='blue', alpha=0.5)
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1) # 两条线之间填充蓝色,透明度0.1

# 设置图形的格式
plt.title("Daily high and low temperatures - 2014", fontsize=24) # 标题
plt.xlabel('', fontsize=16) # x轴
fig.autofmt_xdate() # 绘制斜的x轴标签
plt.ylabel("Temperature(F)", fontsize=16) # y轴
plt.tick_params(axis='both', which='major', labelsize=16) # 刻度标记大小

plt.show()

Python入门笔记(三)_python_41



例6:错误检查

有些文档可能数据不全,缺失数据可能引起异常

例如换这个文档

Python入门笔记(三)_ide_42


这个文档数据不全

Python入门笔记(三)_数据_43


这里就需要修改代码,如下:

import csv                              # 用于分析CSV文件中的数据行
from matplotlib import pyplot as plt # 画图需要
from datetime import datetime # 将字符串转换为对应日期需要

# 从文件中获取最高气温,最低温度和日期
filename = 'death_valley_2014.csv'
with open(filename) as f: # 打开文件,并将结果文件对象存储在f中
reader = csv.reader(f) # 创建与该文件相关联的阅读器对象,并存储在reader中
header_row = next(reader) # 第一行

dates, highs, lows = [], [], [] # 日期,最高温度初始化为空列表
for row in reader: # 遍历每行
try:
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 每行第零个元素
high = int(row[1]) # 最高温度转化为整型
low = int(row[3])
except ValueError:
print(current_date, 'missing data')
else:
dates.append(current_date) # 添加日期
highs.append(high) # 添加温度
lows.append(low)

# 根据数据绘制图像
fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red', alpha=0.5) # alpha指定颜色的透明度,使得红色和蓝色折线看起来更浅
plt.plot(dates, lows, c='blue', alpha=0.5)
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1) # 两条线之间填充蓝色,透明度0.1

# 设置图形的格式
title = 'Daily high and low temperatures - 2014\nDeath Valley, CA'
plt.title(title, fontsize=20) # 标题
plt.xlabel('', fontsize=16) # x轴
fig.autofmt_xdate() # 绘制斜的x轴标签
plt.ylabel("Temperature(F)", fontsize=16) # y轴
plt.tick_params(axis='both', which='major', labelsize=16) # 刻度标记大小

plt.show()

Python入门笔记(三)_json_44


Python入门笔记(三)_数据_45



15.2 json文件

例:存

import json

numbers = [1, 3, 5, 7, 9]

filename = "numbers.json"
with open(filename, 'w') as f_obj:
json.dump(numbers, f_obj)

例:取

import json

filename = "numbers.json"
with open(filename) as f_obj:
numbers = json.load(f_obj)

print(numbers)
[1, 3, 5, 7, 9]



例1:从数据地址下载json文件,这里从GitHub上下载

from __future__ import (absolute_import, division, print_function, unicode_literals)
from urllib.request import urlopen
import json

# 网址:the url
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)
file_urllib = json.loads(req) # 加载json格式
print(file_urllib)

下载得到的数据:

Python入门笔记(三)_python_46


例2:第二种下载方法requests

import requests

# 网址:the url
json_url = 'https://raw.githubusercontent.com/muxuezi/btc/master/btc_close_2017.json'
req = requests.get(json_url) # 读取数据
with open('btc_close_2017_urllib.json', 'w') as f: # 将数据写入文件
f.write(req.text)
file_requests = req.json()

例3:从下载得到的文件中提取数据

import json

"""文件中的数据是多个字典,字典都包含相同的键,对应不同的值,这里遍历所有字典,输出每个字典里键对应的值"""
# 将数据加载到一个列表中
filename = 'btc_close_2017_urllib.json' # 文件
with open(filename) as f: # 打开文件
btc_data = json.load(f) # 加载文件
# 打印每一天的信息
for btc_dict in btc_data: # 遍历字典
date = btc_dict['date'] # 每个字典中都有,日期
month = btc_dict['month'] # 月份
week = btc_dict['week'] # 周
weekday = btc_dict['weekday'] # 周末
close = btc_dict['close'] # 收盘价
print("{} 是 {} 月, 第 {} 周, 星期{}, 收盘价是 {} RMB".format(date, month, week, weekday, close))

数据太多,部分如下

Python入门笔记(三)_json_47

例4:收盘价

import json
import pygal

"""文件中的数据是多个字典,字典都包含相同的键,对应不同的值,这里遍历所有字典,输出每个字典里键对应的值"""
# 将数据加载到一个列表中
filename = 'btc_close_2017_urllib.json' # 文件
with open(filename) as f: # 打开文件
btc_data = json.load(f) # 加载文件
# 打印每一天的信息
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("{} 是 {} 月, 第 {} 周, 星期{}, 收盘价是 {} RMB".format(date, month, week, weekday, close))

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 每一天的信息
for btc_dict in btc_data:
dates.append(btc_dict['date'])
months.append(int(btc_dict['month']))
weeks.append(int(btc_dict['week']))
weekdays.append(btc_dict['weekday'])
close.append(int(float(btc_dict['close'])))

line_chart = pygal.Line(x_label_rotation=20, show_minoe_x_labels=False)
line_chart.title = '收盘价($)'
line_chart.x_labels = dates
N = 20 # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
line_chart.add('收盘价', close)
line_chart.render_to_file('收盘价折线图($).svg')

Python入门笔记(三)_json_48


例5:收盘价对数变换折线图

import json
import pygal
import math
from itertools import groupby

"""文件中的数据是多个字典,字典都包含相同的键,对应不同的值,这里遍历所有字典,输出每个字典里键对应的值"""
# 将数据加载到一个列表中
filename = 'btc_close_2017_urllib.json' # 文件
with open(filename) as f: # 打开文件
btc_data = json.load(f) # 加载文件
# 打印每一天的信息
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("{} 是 {} 月, 第 {} 周, 星期{}, 收盘价是 {} RMB".format(date, month, week, weekday, close))

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 每一天的信息
for btc_dict in btc_data:
dates.append(btc_dict['date'])
months.append(int(btc_dict['month']))
weeks.append(int(btc_dict['week']))
weekdays.append(btc_dict['weekday'])
close.append(int(float(btc_dict['close'])))

"""收盘价折线图"""
line_chart = pygal.Line(x_label_rotation=20, show_minoe_x_labels=False)
line_chart.title = '收盘价($)'
line_chart.x_labels = dates
N = 20 # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
line_chart.add('收盘价', close)
line_chart.render_to_file('收盘价折线图($).svg')

"""收盘价对数变换折线图"""
line_chart = pygal.Line(x_label_rotation=20, show_minoe_x_labels=False)
line_chart.title = '收盘价对数变换($)'
line_chart.x_labels = dates
N = 20 # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
close_log = [math.log10(_) for _ in close] # 这里不一样
line_chart.add('log收盘价', close_log)
line_chart.render_to_file('收盘价对数变换折线图($).svg')

Python入门笔记(三)_ide_49


例6:收盘价周日均值和收盘价星期均值

import json
import pygal
import math
from itertools import groupby

"""文件中的数据是多个字典,字典都包含相同的键,对应不同的值,这里遍历所有字典,输出每个字典里键对应的值"""
# 将数据加载到一个列表中
filename = 'btc_close_2017_urllib.json' # 文件
with open(filename) as f: # 打开文件
btc_data = json.load(f) # 加载文件
# 打印每一天的信息
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("{} 是 {} 月, 第 {} 周, 星期{}, 收盘价是 {} RMB".format(date, month, week, weekday, close))

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 每一天的信息
for btc_dict in btc_data:
dates.append(btc_dict['date'])
months.append(int(btc_dict['month']))
weeks.append(int(btc_dict['week']))
weekdays.append(btc_dict['weekday'])
close.append(int(float(btc_dict['close'])))

"""收盘价折线图"""
line_chart = pygal.Line(x_label_rotation=20, show_minoe_x_labels=False)
line_chart.title = '收盘价($)'
line_chart.x_labels = dates
N = 20 # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
line_chart.add('收盘价', close)
line_chart.render_to_file('收盘价折线图($).svg')

"""收盘价对数变换折线图"""
line_chart = pygal.Line(x_label_rotation=20, show_minoe_x_labels=False)
line_chart.title = '收盘价对数变换($)'
line_chart.x_labels = dates
N = 20 # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
close_log = [math.log10(_) for _ in close]
line_chart.add('log收盘价', close_log)
line_chart.render_to_file('收盘价对数变换折线图($).svg')


def draw_line(x_data, y_data, title, y_legend):
xy_map = []
for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0]):
y_list = [v for _, v in y]
xy_map.append([x, sum(y_list) / len(y_list)])
x_unique, y_mean = [*zip(*xy_map)]
line_chart = pygal.Line() # 画图
line_chart.title = title # 设置标题
line_chart.x_labels = x_unique
line_chart.add(y_legend, y_mean) # 添加了Y轴标签
line_chart.render_to_file(title+'.svg') # 保存为.svg文件
return line_chart


idx_month = dates.index('2017-12-01')
line_chart_month = draw_line(months[:idx_month], close[:idx_month],
'收盘价月日均值($)', '月日均值')
line_chart_month

inx_week = dates.index('2017-12-01')
line_chart_week = draw_line(weeks[:idx_month], close[1:idx_month],
'收盘价周日均值($)', '周日均值')
line_chart_week


idx_week = dates.index('2017-12-11')
wd = ['Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday', 'Sunday']
weekdays_int = [wd.index(w) + 1 for w in weekdays[1:idx_week]]
line_chart_weekday = draw_line(
weekdays_int, close[1:idx_week], '收盘价星期均值($)', '星期均值')
line_chart_weekday.x_labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line_chart_weekday.render_to_file('收盘价星期均值($).svg')
line_chart_weekday

这里图就不贴了

最后:收盘价数据仪表盘

import json
import pygal
import math
from itertools import groupby

"""文件中的数据是多个字典,字典都包含相同的键,对应不同的值,这里遍历所有字典,输出每个字典里键对应的值"""
# 将数据加载到一个列表中
filename = 'btc_close_2017_urllib.json' # 文件
with open(filename) as f: # 打开文件
btc_data = json.load(f) # 加载文件
# 打印每一天的信息
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("{} 是 {} 月, 第 {} 周, 星期{}, 收盘价是 {} RMB".format(date, month, week, weekday, close))

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 每一天的信息
for btc_dict in btc_data:
dates.append(btc_dict['date'])
months.append(int(btc_dict['month']))
weeks.append(int(btc_dict['week']))
weekdays.append(btc_dict['weekday'])
close.append(int(float(btc_dict['close'])))


"""收盘价折线图"""
line_chart = pygal.Line(x_label_rotation=20, show_minoe_x_labels=False)
line_chart.title = '收盘价($)'
line_chart.x_labels = dates
N = 20 # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
line_chart.add('收盘价', close)
line_chart.render_to_file('收盘价折线图($).svg')

"""收盘价对数变换折线图"""
line_chart = pygal.Line(x_label_rotation=20, show_minoe_x_labels=False)
line_chart.title = '收盘价对数变换($)'
line_chart.x_labels = dates
N = 20 # x轴坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
close_log = [math.log10(_) for _ in close]
line_chart.add('log收盘价', close_log)
line_chart.render_to_file('收盘价对数变换折线图($).svg')


def draw_line(x_data, y_data, title, y_legend):
xy_map = []
for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0]):
y_list = [v for _, v in y]
xy_map.append([x, sum(y_list) / len(y_list)])
x_unique, y_mean = [*zip(*xy_map)]
line_chart = pygal.Line() # 画图
line_chart.title = title # 设置标题
line_chart.x_labels = x_unique
line_chart.add(y_legend, y_mean) # 添加了Y轴标签
line_chart.render_to_file(title+'.svg') # 保存为.svg文件
return line_chart


idx_month = dates.index('2017-12-01')
line_chart_month = draw_line(months[:idx_month], close[:idx_month],
'收盘价月日均值($)', '月日均值')
line_chart_month

inx_week = dates.index('2017-12-01')
line_chart_week = draw_line(weeks[:idx_month], close[1:idx_month],
'收盘价周日均值($)', '周日均值')
line_chart_week


idx_week = dates.index('2017-12-11')
wd = ['Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday', 'Sunday']
weekdays_int = [wd.index(w) + 1 for w in weekdays[1:idx_week]]
line_chart_weekday = draw_line(
weekdays_int, close[1:idx_week], '收盘价星期均值($)', '星期均值')
line_chart_weekday.x_labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line_chart_weekday.render_to_file('收盘价星期均值($).svg')
line_chart_weekday

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',
'收盘价周日均值($).svg', '收盘价星期均值($).svg'
]:
html_file.write(
' <object type="image/svg+xml" data="{0}" height=500></object>\n'.format(svg)) # 1
html_file.write('</body></html>')

相当于把上面得到的五张图放在一个HTML文件中

Python入门笔记(三)_数据_50



第十六章. 使用API

16.1 requests

例:找出GitHub中星级最高的python项目
1、先查看能否成功响应

import requests

# 执行API调用并存储响应
url = "https://api.github.com/search/repositories?q=language:python&sort=stars"
r = requests.get(url)
print("Status code:", r.status_code) # 状态码

# 将API响应存储在一个变量中
response_dict = r.json()

# 处理结果
print(response_dict.keys())
Status code: 200
dict_keys(['total_count', 'incomplete_results', 'items'])

2、处理响应字典

import requests

# 执行API调用并存储响应
url = "https://api.github.com/search/repositories?q=language:python&sort=stars"
r = requests.get(url)
print("Status code:", r.status_code) # 状态码

# 将API响应存储在一个变量中
response_dict = r.json()
print("Total repositories:", response_dict['total_count'])

# 探索有关仓库的信息
repo_dicts = response_dict['items']
print("Repositories returned:", len(repo_dicts)) # 打印有多少个仓库数,也就是python项目数

# 研究第一个仓库
repo_dict = repo_dicts[0]
print("\nKeys:", len(repo_dict))
for key in sorted(repo_dict.keys()): # 排序打印
print(key)

Python入门笔记(三)_数据_51


3、继续研究第一个项目

# 研究第一个仓库
repo_dict = repo_dicts[0]
print("\nSelected information about first repository:")
print("Name:", repo_dict['name']) # 项目名字
print("Owner:", repo_dict['owner']['login']) # 所有者
print("Stars:", repo_dict['stargazers_count']) # 星数
print("Repository:", repo_dict['html_url']) # 地址
print("Created:", repo_dict['created_at']) # 创建时间
print("Updated:", repo_dict['updated_at']) # 修改时间
print("Description:", repo_dict['description']) # 项目描述
Status code: 200
Total repositories: 8901091
Repositories returned: 30

Selected information about first repository:
Name: public-apis
Owner: public-apis
Stars: 213233
Repository: https://github.com/public-apis/public-apis
Created: 2016-03-20T23:49:42Z
Updated: 2022-10-28T02:38:42Z
Description: A collective list of free APIs

4、使用Pygal可视化仓库

import requests
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS

# 执行API调用并存储响应
url = "https://api.github.com/search/repositories?q=language:python&sort=stars"
r = requests.get(url)
print("Status code:", r.status_code) # 状态码

# 将API响应存储在一个变量中
response_dict = r.json()
print("Total repositories:", response_dict['total_count'])

# 探索有关仓库的信息
repo_dicts = response_dict['items']

names, stars = [], []
for repo_dict in repo_dicts:
names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])

# 可视化
my_style = LS('#333366', base_style=LCS)
chart = pygal.Bar(style=my_style, x_label_rotation=45, show_legend=False) # 第二参数标签旋转,第三参数隐藏图例
chart.title = "Most-Starred Python Projects on GitHub"
chart.x_labels = names

chart.add('', stars)
chart.render_to_file('python_repos.svg')

Python入门笔记(三)_ide_52


5、调整图像

# 可视化
my_style = LS('#333366', base_style=LCS)

my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_legend = False
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18
my_config.truncate_label = 15
my_config.show_y_guides = False
my_config.width = 1000

chart = pygal.Bar(my_config, style=my_style)
chart.title = "Most-Starred Python Projects on GitHub"
chart.x_labels = names

chart.add('', stars)
chart.render_to_file('python_repos.svg')

Python入门笔记(三)_python_53


标签:plt,入门,Python,self,chart,笔记,dict,btc,line
From: https://blog.51cto.com/u_15902866/5920909

相关文章