python大作业进阶——绘制滚动图

python绘制滚动图


上面就是效果图(结果为MP4视频)
代码展示
1、加载库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']

2、读取文件

df = pd.read_csv('Province_GDP.csv', index_col=0 ,encoding='utf-8')
data = df.to_dict(orient='dict')

3、设定每个省市所用的颜色

# 推荐一个找颜色的网址https://html-color-codes.info/chinese/
colors = {'北京市': '#FFA500',
          '天津市': '#1E90FF',
         '河北省': '#FF0000',
         '山西省': '#FF1493',
         '内蒙古自治区': '#127436',
         '辽宁省': '#FAA460',
         '吉林省': '#9400D3',
         '黑龙江省': '#8B0000',
         '上海市': '#C0C0C0',
         '江苏省': '#87CEEB',
         '浙江省': '#8FBC8F',
         '安徽省': '#FFFF00',
         '福建省': '#C71585',
         '江西省': '#800080',
         '山东省': '#FF8C00',
         '河南省': '#E60000',
         '湖北省': '#BDB76B',
         '湖南省': '#FFA500',
         '广东省': '#008000',
         '广西壮族自治区': '#000000',
         '海南省': '#E5EE2E',
         '重庆市': '#777777',
         '四川省': '#0000FF',
         '贵州省': '#CD5C5C',
         '云南省': '#20B2AA',
         '西藏自治区': '#E6D933',
         '陕西省': '#00BFFF',
         '甘肃省': '#191970',
         '青海省': '#D1F417',
         '宁夏回族自治区': '#FF69B4',
         '新疆维吾尔族自治区': '#75D6F2'}

4、将时间段单独抽出作为一个列表,另外生成一个存放数据的列表,且对应每个时间段的各省的GDP由大到小进行排序

date = []
number_sort = []
for key, value in data.items():
    date.append(key)
    number_sort.append(sorted(value.items(), key=lambda d:d[1], reverse = True))

5、设计算法,生成视频每一帧所需要的图片
以下为主程序,每一步均有注释,不做详细分布说明

count = 0 # 
for i in range(len(number_sort)):
    provinces_now = {} # 本年的排序
    provinces_next = {} # 后一年的排序
    # 由于最后一组数据与前几组数据处理不同,先处理前几组数据
    if i !=len(number_sort)-1:
        for (province,gdp) in number_sort[i]:
            provinces_now[province] = gdp # 将本年的数据写入字典
        for (province,gdp) in number_sort[i + 1]:
            provinces_next[province] = gdp # 将下一年的数据写入字典
        provinces_rank_now = list(provinces_now.keys())
        provinces_rank_next = list(provinces_next.keys())

        #设置0矩阵用于位次的记录
        provinces_rank_change = np.zeros((31))

        #讲位次的改变记录在矩阵中
        for j in range(31):
            provinces_rank_change[j] = provinces_rank_next.index(provinces_rank_now[j]) - j
        #由于之后每一年的数据以30张图片输出,所以这里÷30来分配每一帧的数据变化
        provinces_rank_per_change = list(provinces_rank_change / 30)

        #将排序好的省份以及当前顺序写入字典中
        provinces_rank_record = {}
        for j in range(31):
            provinces_rank_record[provinces_rank_now[j]] = j + 1

        #设置0矩阵用于差值的计算,也为后续的数据变化做准备
        provinces_data_change = np.zeros((31))
        for j in range(31):
            provinces_data_change[j] = provinces_next[provinces_rank_now[j]] - provinces_now[provinces_rank_now[j]]
        #由于之后每一年的数据以30张图片输出,所以这里÷30来分配每一帧的数据变化
        provinces_data_per_change = list(provinces_data_change / 30)
        
        #由于数据较多,模拟靠前的一半输出
        for k in range(30):
            # 先准备一些格式较多的数据以免后续使用
            # 开一个ax的绘图面板
            fig, ax = plt.subplots(figsize=(19.2,10.8), dpi=100)
            #省份名字和排行
            provinces_name_rank = sorted(provinces_rank_record.items(),key=lambda x:x[1],reverse=False)[:15]
            #省份名字和GDP数据
            provinces_name_data = sorted(provinces_now.items(),key=lambda x:x[1],reverse=True)[:15]
            #省份排序
            provinces = [w[0] for w in provinces_name_rank]
            #顺序 其实就是1-15的排序,也可range(1,16)
            provinces_r = [w[1] for w in provinces_name_rank]
            #数据 按顺序排序的数据(GDP值)
            provinces_d = [provinces_now[w] for w in provinces]
            #省份所对应的颜色
            color = []
            for province in provinces:
                color.append(colors[province])
                
            # 以横向的柱状图展现,并设置参数
            # matplotlib绘制图表参考https://blog.csdn.net/weixin_40683253/article/details/87641416
            b = ax.barh(provinces_r,provinces_d,0.5, # x轴,y轴,柱条宽度
                        edgecolor = 'white', # 边框颜色
                        color = color, # 填充颜色
                        tick_label = provinces, # 图例
                        alpha = 0.7) #透明度
            
            # pyplot.text的用法参考https://blog.csdn.net/The_Time_Runner/article/details/89927708
            # ha、va的用法参考https://blog.csdn.net/qq_39131592/article/details/79056255
            for rect in b:
                w = rect.get_width()
                #print(w)
                #print(rect.get_y())
                #print(rect.get_y() + rect.get_height()/2)
                ax.text(w + 1500, rect.get_y() + rect.get_height()/2,
                        '%d'%w, # 注释内容
                        ha='left',# 垂直对齐方式
                        va='center')# 水平对齐方式
            
            # 隐藏上边和右边的坐标轴
            # 参考https://blog.csdn.net/qq_41011336/article/details/83015986
            ax.spines['right'].set_color('none')
            ax.spines['top'].set_color('none')
            
            # 添加对应的年份
            ax.text( 7 * b[0].get_width()/10, 12 ,date[i],fontsize=28)
            ax.text( 6 * b[0].get_width()/10, 11 ,'处于领跑状态的省份是:{}'.format(provinces[0]),fontsize=27)
            # 绘制整个图像的标题
            plt.title('全国各省2010-2018年GDP变化', fontsize=29)
            # 保存图片,文件名自己修改
            plt.savefig('picture/{} {}.png'.format('%02d'%i, '%02d'%k))
            # 关闭plt
            plt.close('all')
            #数据更新迭代,加上已经准备好的差值
            for t in range(31):
                provinces_rank_record[provinces_rank_now[t]] += provinces_rank_per_change[t]
                provinces_now[provinces_rank_now[t]] += provinces_data_per_change[t]
            count+=1
            print('已完成{:.2%}'.format(count/243))
    else:
        # 几乎复制上一段代码
        for k in range(3):
            #由于是最后一组数据,没有滚动展示,只做两张图片处理,其余与上面相同
            for (province,gdp) in number_sort[i]:
                provinces_now[province] = gdp
            fig, ax = plt.subplots(figsize=(19.2,10.8), dpi=100)
            provinces_fin_rank = sorted(provinces_rank_record.items(),key=lambda x:x[1],reverse=False)[:15]
            provinces = [w[0] for w in provinces_fin_rank]
            provinces_r = [w[1] for w in provinces_fin_rank]
            provinces_d = [provinces_now[w] for w in provinces]
            color = []
            for province in provinces:
                color.append(colors[province])
            
            b = ax.barh(provinces_r,provinces_d,0.5,edgecolor = 'white',color = color, tick_label = provinces, alpha = 0.7)
            for rect in b:
                w = rect.get_width()
                ax.text(w + 1500, rect.get_y() + rect.get_height()/2, '%d'%w, ha='left', va='center')
            ax.spines['right'].set_color('none')
            ax.spines['top'].set_color('none')
            ax.text( 7 * b[0].get_width()/10, 12 ,date[i],fontsize=28)
            ax.text( 6 * b[0].get_width()/10, 11 ,'处于领跑状态的省份是:{}'.format(provinces[0]),fontsize=27)
            ax.text( 7 * b[0].get_width()/10, 10 ,'谢谢观看',fontsize=28)
            plt.title('全国各省2010-2018年GDP变化', fontsize=29)
            plt.savefig('picture/{} {}.png'.format('%02d'%i, '%02d'%k))
            plt.close('all')
            count+=1
            print('已完成{:.2%}'.format(count/243))
print('图片保存完成,请进行后续程序,感谢您耐心的等待。')

6、利用opencv将图片合成视频

# 将图片合成视频用到opencv,参考https://blog.csdn.net/qq_33287871/article/details/100065144
import cv2
import os
# 帧率即每秒钟展示多少张图片
fps = 30
# 图片大小信息
size = (1920, 1080)
#音视频封装格式编码格式,参考https://blog.csdn.net/ubuntulover/article/details/6219056
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
videowriter = cv2.VideoWriter("province.mp4",fourcc, fps, size)
# 文件地址
path = r'C:\Users\52287\picture\\'
# 合成视频
for i in os.listdir(path):
    img = cv2.imread(path + i)
    videowriter.write(img)
videowriter.release()

代码中存在的路径自己修改,源码地址

https://pan.baidu.com/s/1uEcc4lLa0ZFVB_bNJEmNIg
提取码:bomj

全部评论

相关推荐

Hello_WordN:咱就是说,除了生命其他都是小事,希望面试官平安,希望各位平时也多注意安全
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务