美文网首页
Python编程从入门到实践:数据处理与可视化

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

作者: leacoder | 来源:发表于2019-04-07 01:39 被阅读0次

    开发系统和开发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/
    欢迎大家来一起交流学习

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/oycjiqtx.html