Python编程从入门到实践:数据处理与可视化

开发系统和开发IDE

开发系统: Ubuntu 16.0.4 LTS
开发IDE: Visual Studio Code 版本: 1.32.3
Python版本: Python3
依赖库: pygame

资料《Python编程从入门到实践》书籍

链接:https://pan.baidu.com/s/1USkqvL2dLU3Q9XplVaGQJg
提取码:zoyc

GitHub:

https://github.com/lichangke/Python3_Project/tree/master/data_visual

相关第三方库

matplotlib:https://matplotlib.org/

sudo apt-get install python3-matplotlib

pygal:http://www.pygal.org/en/stable/

pip install --user pygal

pip install pygal_maps_world 额外需安装

matplotlib 随机漫步

matplotlib 简单使用,访问相关第三方库中链接了解更多

目录文件结构

随机漫步.png
# 文件名 内容
- mpl_squares.py 绘制折线图
- random_walk.py Python来生成随机漫步数据
- rw_visual.py 循环生成随机漫步数据并生成显示图像,需random_walk.py
- scatter_squares.py 绘制散点图

随机漫步数据显示图像

随机漫步1.png

mpl_squares.py

'''
@File    :   mpl_squares.py
@Time    :   2019/04/06 16:45:51
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   绘制折线图
'''
# here put the import lib
# 导入了模块pyplot 

import matplotlib.pyplot as plt

input_values = [1, 2, 3, 4, 5] # X 轴数据

squares = [1, 4, 9, 16, 25] # Y 轴数据
'''
plot(*args[, scalex, scaley, data])
绘制 x y 坐标组成的线
'''
plt.plot(input_values, squares, linewidth=5)

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

# 设置刻度标记的大小
plt.tick_params( axis = 'both', labelsize = 14 , colors = 'r' ) # axis 将参数应用于哪个轴

plt.show()  
'''
打开matplotlib查看器, 并显示绘制的图形
'''

random_walk.py

'''
@File    :   random_walk.py
@Time    :   2019/04/06 17:39:26
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   Python来生成随机漫步数据
'''

# here put the import lib
from random import choice

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

    def __init__(self, num_points=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_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_visual.py

'''
@File    :   rw_visual.py
@Time    :   2019/04/07 00:56:52
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   循环生成随机漫步数据并显示
'''

# here put the import lib


import matplotlib.pyplot as plt
from random_walk import RandomWalk


# 只要程序处于活动状态, 就不断地模拟随机漫步
while True:
    rw = RandomWalk(50000)
    rw.fill_walk()

    '''
    figure([num, figsize, dpi, facecolor, ...])
        Create a new figure.
        figsize : (float, float), optional, default: None
            width, height in inches. If not provided, defaults to rcParams["figure.figsize"] = [6.4, 4.8].
        dpi : integer, optional, default: None
            resolution of the figure. If not provided, defaults to rcParams["figure.dpi"] = 100.
    '''
    # 设置绘图窗口的尺寸
    plt.figure(figsize=(10, 6),dpi=128)

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

    # 突出起点和终点
    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)

    '''
    The Axes class The Axes contains most of the figure elements: Axis, Tick, Line2D, Text, Polygon, etc., and sets the coordinate system.
    '''
    # 隐藏坐标轴
    plt.axes().get_xaxis().set_visible(False)   # Return the XAxis instance.
    plt.axes().get_yaxis().set_visible(False)   # Return the YAxis instance.

    plt.show()
    keep_running = input("Make another walk? (y/n): ")
    if keep_running == 'n':
        break

scatter_squares.py

'''
@File    :   scatter_squares.py
@Time    :   2019/04/06 17:08:01
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   绘制散点图
'''

# here put the import lib
import matplotlib.pyplot as plt

'''
scatter(x, y[, s, c, marker, cmap, norm, ...])
绘制x y 坐标的散点图,并设置不同的 标记 大小 或 颜色等。
'''

x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]
color = ['r', 'g', 'b']

# s 标记大小 以磅为单位**2  c 颜色,序列或颜色序列
plt.scatter(x_values, y_values, s=100, c=color)

# 设置图表标题并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)

plt.show()


# 循环绘制1000个点

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


'''
c : color, sequence, or sequence of color, optional
    A single color format string.
    A sequence of color specifications of length n.
    A sequence of n numbers to be mapped to colors using cmap and norm.  #使用cmap和norm映射到颜色的n个数字序列
    A 2-D array in which the rows are RGB or RGBA.

cmap : Colormap, optional, default: None  # cmap 告诉pyplot 使用哪个颜色映射

edgecolors : color or sequence of color, optional, default: 'face' # 边框颜色

'''

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

# 设置图表标题并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)

'''
axis(*v, **kwargs)
获取或设置某些轴属性的便捷方法
xmin, xmax, ymin, ymax = axis()
xmin, xmax, ymin, ymax = axis(xmin, xmax, ymin, ymax)
xmin, xmax, ymin, ymax = axis(option)
xmin, xmax, ymin, ymax = axis(**kwargs)
'''
# 设置每个坐标轴的取值范围
plt.axis([0, 1100, 0, 1100000])

plt.show()

pygal 模拟掷骰子

pygal 简单使用,访问相关第三方库中链接了解更多

目录文件结构

模拟色子.png
# 文件名 内容
- die.py 骰子类
- die_visual.py 模拟掷骰子并柱状图显示点数出现次数,需die.py
- die_visual.svg 生成的svg,可用浏览器打开

die_visual.svg

模拟色子1.png

die.py

'''
@File    :   die.py
@Time    :   2019/04/06 21:53:11
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   骰子类
'''

# here put the import lib

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)
        '''
        def randint(a, b)
            Return random integer in range [a, b], including both end points.
        '''

die_visual.py

'''
@File    :   die_visual.py
@Time    :   2019/04/06 21:56:06
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   模拟掷骰子并柱状图显示点数出现次数
'''

# here put the import lib

from die import Die

import pygal

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

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


# 分析结果
frequencies = []
max_result = die_1.num_sides + die_2.num_sides
for value in range(2, max_result+1):
    frequency = results.count(value)
    frequencies.append(frequency)

# 对结果进行可视化
hist = pygal.Bar()  # Basic simple bar graph:

hist.title = "Results of rolling a D8 and a D8 50,000  times."
x_labels = set()
for i in range(1,die_1.num_sides+1):
    for j in range(1, die_2.num_sides+1):
        x_label = i + j
        x_labels.add(x_label)

print(x_labels)

hist.x_labels = list(x_labels)
hist.x_title = "Result"
hist.y_title = "Frequency of Result"
# 使用add() 将一系列值添加到图表中(向它传递要给添加的值指定的标签, 还有一个列表, 其中包含将出现在图表中的值) 。
hist.add('D8 + D8', frequencies)
hist.render_to_file('die_visual.svg')  # 最后, 我们将这个图表渲染为一个SVG文件

matplotlib绘制温度折线图

对CSV文件格式的数据处理,通过matplotlib绘制CSV文件中温度数据的折线图

目录文件结构

CSV数据.png
# 文件名 内容
- highs_lows.py 处理CSV文件数据,matplotlib绘制最高温度最低温度折线图
- 其他.csv csv格式的温度数据

最高温度最低温度折线图

最高温度最低温度.png

highs_lows.py

'''
@File    :   highs_lows.py
@Time    :   2019/04/06 22:32:59
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   处理CSV文件数据,matplotlib绘制最高温度最低温度折线图
'''

# here put the import lib

# c sv 模块包含在Python标准库中
import csv

from matplotlib import pyplot as plt
# 模块datetime 处理日期
from datetime import datetime

# 从文件中获取日期、 最高气温和最低气温
filename = 'death_valley_2014.csv'

with open(filename) as f:
        # 创建一个与该文件相关联的阅读器(reader ) 对象
    reader = csv.reader(f)
    # 模块csv 包含函数next() , 调用它并将阅读器对象传递给它时, 它将返回文件中的下一行。 在前面的代码中, 我们只调用了next() 一次, 因此得到的是文件的第一行, 其中包含文件头
    header_row = next(reader)

    dates, highs, lows = [], [], []
    for row in reader:  # 遍历文件中余下的各行
        try: # 错误检查
            current_date = datetime.strptime(row[0], "%Y-%m-%d")  # '2014-7-1
            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=123, figsize=(10, 6))

'''
plot(*args[, scalex, scaley, data])
    Plot y versus x as lines and/or markers.
        alpha: float  Set the alpha value used for blending - not supported on all backends.
'''
plt.plot(dates, highs, c='red', alpha=0.5)  # 绘制最高温度
plt.plot(dates, lows, c='blue', alpha=0.5)  # 绘制最低温度

'''
fill_between(x, y1[, y2, where, ...])
    Fill the area between two horizontal curves.
'''
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)

# 设置图形的格式
plt.title("Daily high temperatures - 2014", fontsize=24)
plt.xlabel('', fontsize=16)
'''
autofmt_xdate(self, bottom=0.2, rotation=30, ha='right', which=None)
    Date ticklabels often overlap, so it is useful to rotate them and right align them.
    bottom : scalar
        The bottom of the subplots for subplots_adjust().
    rotation : angle in degrees
        The rotation of the xtick labels.
    ha : string
        The horizontal alignment of the xticklabels.
    which : {None, 'major', 'minor', 'both'}
        Selects which ticklabels to rotate. Default is None which works the same as major.


'''
fig.autofmt_xdate()

title = "Daily high and low temperatures - 2014\nDeath Valley, CA"
plt.title(title, fontsize=24)

'''
tick_params([axis])
    Change the appearance of ticks, tick labels, and gridlines. 更改刻度,刻度标签和网格线的外观
    axis : {'x', 'y', 'both'}, optional
        Which axis to apply the parameters to.
    which : {'major', 'minor', 'both'}
        Default is 'major'; apply arguments to which ticks.
'''
plt.tick_params(axis='both', which='major', labelsize=16)

plt.show()

pygal绘制世界人口地图

对json文件格式的数据处理,通过pygal绘制世界人口地图

目录文件结构

json数据.png
# 文件名 内容
- country_codes.py 处理国家识别码
- population_data.json json文件格式的数据
- world_population.py 对json文件格式的数据处理,通过pygal绘制世界人口地图,需country_codes.py
- world_population.svg 绘制生成的世界人口地图

世界人口地图

世界人口地图.png

country_codes.py

'''
@File    :   countries.py
@Time    :   2019/04/06 23:42:39
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   处理国家识别码
'''

# here put the import lib

# from pygal.i18n import COUNTRIES 模块已被遗弃 但是现在可以在 pygal_maps_world 插件中找到它  pip3 install pygal_maps_world

from pygal.maps.world import COUNTRIES


def get_country_code(country_name):
    """根据指定的国家, 返回Pygal使用的两个字母的国别码"""
    for country_code in sorted(COUNTRIES.keys()):
        for code, name in COUNTRIES.items():
            if name == country_name:
                return code

        # 如果没有找到指定的国家, 就返回None
        return None

world_population.py

'''
@File    :   world_population.py
@Time    :   2019/04/06 23:36:41
@Author  :   leacoder
@Version :   1.0
@Contact :   leacock1991@gmail.com
@License :   
@Desc    :   对json文件格式的数据处理,通过pygal绘制世界人口地图
'''

# here put the import lib

''' 导入画地图的模块 '''
import pygal.maps.world

''' 解析json文件 '''
import json

'''世界地图的样式'''
import pygal
from pygal.style import RotateStyle  # 十六进制颜色
from pygal.style import LightColorizedStyle # 加亮地图的颜色

from country_codes import get_country_code


# 将数据加载到一个列表中
filename = 'population_data.json'
with open(filename) as f:
    pop_data = json.load(f)

# 创建一个包含人口数量的字典
cc_populations = {}

for pop_dict in pop_data:
    if pop_dict['Year'] == '2010':
        country_name = pop_dict['Country Name']
        # population = int(pop_dict['Value']) # '1127437398.85751'  Python不能直接将包含小数点的字符串'1127437398.85751' 转换为整数
        # 先将字符串转换为浮点数, 再将浮点数转换为整数:
        population = int(float(pop_dict['Value']))

        code = get_country_code(country_name)
        if code:
            cc_populations[code] = population
        else:
            print('ERROR - ' + country_name)

# 根据人口数量将所有的国家分成三组
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for cc, pop in cc_populations.items():

    if pop < 10000000:
        cc_pops_1[cc] = pop
    elif pop < 1000000000:
        cc_pops_2[cc] = pop
    else:
        cc_pops_3[cc] = pop

# 看看每组分别包含多少个国家
print(len(cc_pops_1), len(cc_pops_2), len(cc_pops_3))
    
'''
class pygal.style.RotateStyle(color, step=10, max_=None, base_style=None, **kwargs)
    Create a style by rotating the given color
'''
wm_style = RotateStyle('#336699', base_style=LightColorizedStyle) # 十六进制颜色码 
# wm = pygal.Worldmap()  # 已不可用 使用.maps.world.World()替代
wm = pygal.maps.world.World()  # 初始化一个地图对象
wm.style = wm_style # 设置地图的风格
wm.title = 'World Population in 2010, by Country'
#wm.add('2010', cc_populations)
wm.add('0-10m', cc_pops_1)
wm.add('10m-1bn', cc_pops_2)
wm.add('>1bn', cc_pops_3)
wm.render_to_file('world_population.svg')


GitHub链接:
https://github.com/lichangke/LeetCode
知乎个人首页:
https://www.zhihu.com/people/lichangke/
简书个人首页:
https://www.jianshu.com/u/3e95c7555dc7
个人Blog:
https://lichangke.github.io/
欢迎大家来一起交流学习

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容

  • 第十五章 生成数据 matplotlib数学绘图库 pygal专注生成适合在数字设备上显示的图表 15.1 绘制折...
    Shinichi新一君阅读 1,016评论 0 0
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    小迈克阅读 2,921评论 1 3
  • youtube下载神器:https://github.com/rg3/youtube-dl 我擦咧 vim插件:h...
    smart_small阅读 8,725评论 2 47
  • 长恨歌 唐 · 白居易 汉皇重色思倾国,御宇多年求不得。 杨家有女初长成,养在深闺人未识。 天生丽质难自弃,一朝选...
    漂泊的小森阅读 182评论 0 2
  • OSI七层模型 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要...
    须臾_0d97阅读 147评论 0 0