• 基于python实现的图像绘制(二维散点图、饼图,绘制三维的直方图、线图、散点图、利用pyecharts在地图上绘制各种图标)


    1. 问题描述

    • 使用 Iris 数据集,在一个 figure 中绘制出右侧的 16 个子图。

      分别使用花瓣长度、花瓣宽度、花萼长度和花萼宽度这四种数据,两两组合,形成散点。

    • 找一组自己感兴趣的真实数据,绘制出饼图。并看看数据的项数在什么范围比较合适在饼图中展示;

      调整数据的顺序或角度,使得第一个扇区在 12 点方向开始;

      调整字体的大小、标签的位置等参数。

    • 在中国地图上展示每个省的高考人数或大学数量。

    • 展示自己家乡所在城市的温度变化热力图,要求至少有 10 天的数据。

    • 生成一个直方图,有 25 根直方柱。要求直方柱的最小值是 1,最大值是 25,要求沿着边缘,从外到内逐步增大

    • 生成一个金字塔的线图;

      生成一上一下两个金字塔,叠放在一起。

    • 生成一个散点图,z=x2+y2

    2. 实验环境

    Microsoft Windows 10 版本18363

    ​ PyCharm 2020.2.1 (Community Edition)

    ​ Python 3.8(Scrapy 2.4.0 + numpy 1.19.4 + pandas 1.1.4 + matplotlib 3.3.3)

    3. 实验步骤及结果

    • 使用 Iris 数据集,在一个 figure 中绘制出右侧的 16 个子图。

      分别使用花瓣长度、花瓣宽度、花萼长度和花萼宽度这四种数据,两两组合,形成散点。

    from matplotlib import pyplot as plt
    import numpy as np
    import pandas as pd
    
    from pylab import *
    mpl.rcParams['font.sans-serif'] = ['SimHei']
    
    df = pd.read_csv("./iris.csv", encoding='utf-8', dtype=str)
    df = pd.DataFrame(df, columns=['Sepal.length', 'Sepal.width', 'Petal.Length', 'Petal.Width', 'Species'], dtype=str)
    
    colors = ['blue', 'orange', 'green']
    
    df['Sepal.length'] = df['Sepal.length'].astype(np.float)
    df['Sepal.width'] = df['Sepal.width'].astype(np.float)
    df['Petal.Length'] = df['Petal.Length'].astype(np.float)
    df['Petal.Width'] = df['Petal.Width'].astype(np.float)
    
    Species = df.Species.unique()
    print(Species)
    
    fig, ax = plt.subplots()
    
    labelx = ['Petal.Width', 'Petal.Length', 'Sepal.width', 'Sepal.length']
    labely = ['Sepal.length', 'Sepal.width', 'Petal.Length', 'Petal.Width']
    
    for index in range(16):
        plt.subplot(4, 4, index + 1)
        plt.xlabel(labelx[index % 4])
        plt.ylabel(labely[int(index / 4)])
        plt.title(labelx[index % 4] + ' vs ' + labely[int(index / 4)])
        plt.grid(True, linestyle='--', alpha=0.8)
        for i in range(len(Species)):
            plt.scatter(df.loc[df.Species == Species[i], labelx[index % 4]], df.loc[df.Species == Species[i], labely[int(index / 4)]], s=5, color=colors[i], label=Species[i])
    
    
    plt.subplots_adjust(left=None, bottom=None, right=None, top=None,
                    wspace=1, hspace=1)
    plt.show()
                  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    • 找一组自己感兴趣的真实数据,绘制出饼图。并看看数据的项数在什么范围比较合适在饼图中展示;

      调整数据的顺序或角度,使得第一个扇区在 12 点方向开始;

      调整字体的大小、标签的位置等参数。

      选用了之前北京 2010-2015 年 PM 值状况所对应的的空气质量等级进行了饼图展示,调整了字体大小、位置、饼图大小、每一块的顺序(顺逆时针)、初始块的角度等。

    from matplotlib import pyplot as plt
    import numpy as np
    import pandas as pd
    
    from pylab import *
    mpl.rcParams['font.sans-serif'] = ['SimHei']
    
    section = [0, 35, 75, 115, 150, 250, 99999]
    section_name = ["优", "良", "轻度污染", "中度污染", "重度污染", "严重污染"]
    
    orig_df = pd.read_csv("./BeijingPM20100101_20151231.csv", encoding='utf-8', dtype=str)
    orig_df = pd.DataFrame(orig_df, columns=['year', 'month', 'day', 'PM_US Post'])
    df = orig_df.dropna(0, how='any')
    
    df['PM_US Post'] = df['PM_US Post'].astype(np.int)
    
    result = pd.DataFrame(pd.cut(df['PM_US Post'], section, labels=section_name, ordered=False))
    result_count = result['PM_US Post'].value_counts(sort=False)
    
    plt.pie(result_count, labels=result_count.index, startangle=90, counterclock=False, radius=1.5, textprops={'fontsize':8}, labeldistance=0.5)
    plt.show()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    可以发现该饼图的严重污染部分已经发生了错位,因而饼图适合于 5~6 块,即最小块不要小于 15% 左右会比较好看。

    • 在中国地图上展示每个省的高考人数或大学数量

      选择展示各省/市的公办本科大学数量。

     from pyecharts import options as opts
    from pyecharts.charts import Map
    import numpy as np
    import pandas as pd
    import random
    
    df = pd.read_csv("./中国大学数量.csv", encoding='utf-8', dtype=np.str)
    df = pd.DataFrame(df, columns=['省/市', '公办本科大学数量'])
    df['省/市'] = df['省/市'].astype(np.str)
    df['公办本科大学数量'] = df['公办本科大学数量'].astype(np.int)
    
    class Data:
        @staticmethod
        def province() -> list:
            res = []
            for i in range(len(df)):
                res.append(str(df['省/市'][i]))
            return res
    
        @staticmethod
        def values() -> list:
            res = []
            for i in range(len(df)):
                res.append(int(df['公办本科大学数量'][i]))
            return res
    
    
    def map2() -> Map:
        c = (
            Map()
                .add("数量", [list(z) for z in zip(Data.province(), Data.values())], "china").set_global_opts(
                title_opts=opts.TitleOpts(title="各省公办本科大学数量"),
                visualmap_opts=opts.VisualMapOpts(min_=int(df['公办本科大学数量'].min()), max_=int(df['公办本科大学数量'].max())))
                .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
        )
        return c
    
    
    map2().render("map2.html")             
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    • 展示自己家乡所在城市的温度变化热力图,要求至少有 10 天的数据。

      选取深圳市作图,爬取如下网址未来十天深圳市的天气数据

      https://www.tianqi.com/shenzhen/15/](https://www.tianqi.com/shenzhen/15/)

    import scrapy
    from weather.items import WeatherItem
    
    class TianqiSpider(scrapy.Spider):
        name = 'tianqi'
        allowed_domains = ['tianqi.com']
        start_urls = ['https://www.tianqi.com/shenzhen/15']
    
        def parse(self, response):
            item = WeatherItem()
            data = response.xpath('//ul[@class="weaul"]/li')
            for each in data:
                item['date'] = each.xpath('a/div[1]/span[1]/text()').extract()
                low = each.xpath('a/div[4]/span[1]/text()').extract()[0]
                high = each.xpath('a/div[4]/span[2]/text()').extract()[0]
                item['temperature'] = str((int(low) + int(high)) / 2)
                yield item
            pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    爬虫代码及结果如上

    from pyecharts import options as opts
    from pyecharts.charts import Geo
    from pyecharts.globals import ChartType
    from pyecharts.render import make_snapshot
    from snapshot_phantomjs import snapshot
    import pandas as pd
    import numpy as np
    
    df = pd.read_csv("./weather.csv", encoding='utf-8', dtype=np.str)
    df = pd.DataFrame(df, columns=['temperature'])
    df['temperature'] = df['temperature'].astype(np.float)
    day = 0
    
    class Data:
        guangdong_city = ["深圳市"]
    
        @staticmethod
        def values() -> list:
            res = []
            for i in range(len(df)):
                res.append(float(df['temperature'][i]))
            return res
    
    def geo_guangdong(title) -> Geo:
        c = (
            Geo()
            .add_schema(maptype="广东")
            .add(
                title,
                [list(z) for z in zip(Data.guangdong_city, [Data.values()[day]])],
                type_=ChartType.HEATMAP,
            )
            .set_global_opts(
                visualmap_opts=opts.VisualMapOpts(min_=0, max_=int(df['temperature'].max())),#is_piecewise=True),
                title_opts=opts.TitleOpts(title="广东省深圳市12月13-27日温度变化情况"),
            )
        )
        return c
    
    for i in range(10):
        day = i
        str_date="12月" + str(i+13) + "日"
        make_snapshot(snapshot, geo_guangdong(str_date).render(),
                      str(i+1)+".png", pixel_ratio=1)
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    生成 10 天热力图代码如上。

    在这里插入图片描述

    其中一张如上,其余另附。

    • 生成一个直方图,有 25 根直方柱。要求直方柱的最小值是 1,最大值是 25,要求沿着边缘,从外到内逐步增大
    import numpy as np
    import matplotlib.pyplot as plt
    import math
    from mpl_toolkits.mplot3d import Axes3D
    
    #1.生成fig对象和ax对象
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.set_xlabel('X Label')
    ax.set_ylabel('Y Label')
    ax.set_zlabel('Z Label')
    
    #2.生成数据
    x = []
    y = []
    z = [i + 1 for i in range(25)]
    
    left = up = -1
    down = right = 5
    px = py = 0
    x.append(px)
    y.append(py)
    
    def add(px, py):
        x.append(px)
        y.append(py)
    
    while True:
        if px == 2 and py == 2:
            break
        while py + 1 < down:
            py = py + 1
            add(px, py)
        left = left + 1
        while px + 1 < right:
            px = px + 1
            add(px, py)
        down = down - 1
        while py - 1 > up:
            py = py - 1
            add(px, py)
        right = right - 1
        while px - 1 > left:
            px = px - 1
            add(px, py)
        up = up + 1
    
    bottom = [0 for _ in range(25)]
    width = depth = 0.5
    
    #3.调用bar3d,画3D直方图
    ax.bar3d(x, y, bottom, width, depth, z, shade=True)
    
    #4.显示图形
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    在这里插入图片描述

    • 生成一个金字塔的线图;

      生成一上一下两个金字塔,叠放在一起。

    import numpy as np
    import matplotlib.pyplot as plt
    import math
    from mpl_toolkits.mplot3d import Axes3D
    
    #1.生成fig对象和ax对象
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.set_xlabel('X Label')
    ax.set_ylabel('Y Label')
    ax.set_zlabel('Z Label')
    
    #2.生成数据
    x = np.array([1,0,2,1,2,2,1,2,0,1,0,0])
    y = np.array([1,0,0,1,0,2,1,2,2,1,2,0])
    z = np.array([1,0,0,1,0,0,1,0,0,1,0,0])
    z_minus = -1 * z;
    
    #3.调用plot,画3D的线图
    ax.plot(x,y,z_minus,"b",marker='o')
    ax.plot(x,y,z,"r",marker='o')
    
    #4.显示图形
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述
    在这里插入图片描述

    • 生成一个散点图,z=x2+y2
    import numpy as np
    import matplotlib.pyplot as plt
    import random
    import math
    from mpl_toolkits.mplot3d import Axes3D
    
    #1.生成fig对象和ax对象
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.set_xlabel('X Label')
    ax.set_ylabel('Y Label')
    ax.set_zlabel('Z Label')
    
    #2.生成数据
    x = np.linspace(-100,100,10000)
    np.random.shuffle(x)
    y = np.linspace(-100,100,10000)
    np.random.shuffle(y)
    z = x**2 + y**2 - 20000
    z_minus = -1 * z
    ax.scatter(x, y, z, zdir='z', s=1, c='r', marker='.', depthshade=True)
    ax.scatter(x, y, z_minus, zdir='z', s=1, c='b', marker='.', depthshade=True)
    
    #4.显示图形
    plt.show()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述

  • 相关阅读:
    乱写的项目
    阿里巴巴首推 2022 年金九银十 1000 道 Java 工程师面试题手册(P7岗),整整的10w字文档
    C++——priority_queue类的模拟实现
    我的创作纪念日
    【安全】漏洞挖掘之王的传奇人生
    多普勒流速仪的功能作用是什么?
    全球变暖问题(floodfill 处理联通块问题)
    独立站,如何提高网站转化率
    C++——C++入门(二)
    Python爬虫教程:解析网页中的元素
  • 原文地址:https://blog.csdn.net/newlw/article/details/126136346