前言

动态排名变化的图一直受到欢迎,不过很多事js的方法,少有用python完成的。即便有用python完成的,分享的文章也过于复杂,不利于快速上手。

快速开始

我就给出一个简单的例子,帮助大家快速上手

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
df = pd.DataFrame([["A", 1, 2019], ["B", 2, 2019], ["A", 2, 2020], ["B", 3, 2020]], columns=["name", "value", "year"]) # 构造测试数据
fig, ax = plt.subplots() # 准备画板
def draw_one_year(year): # 绘制单帧
    cur_df = df[df["year"]==year].sort_values(by="value")
    ax.barh(cur_df["name"], cur_df["value"], color=["r", "g"])
animator = animation.FuncAnimation(fig, draw_one_year, frames=range(2019, 2021)) # 动态绘制
animator.save("./test.gif") # 保存数据

没错就这么几行,就能实现一个动态的条形图。
在这里插入图片描述
但是图中没有体现出年份的内容、条形右侧有没有具体的值,可以进一步完善一下。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
df = pd.DataFrame([["A", 1, 2019], ["B", 2, 2019], ["A", 2, 2020], ["B", 3, 2020]], columns=["name", "value", "year"]) # 构造测试数据
fig, ax = plt.subplots() # 准备画板
def draw_one_year(year): # 绘制单帧
    cur_df = df[df["year"]==year].sort_values(by="value")
    ax.clear() # 需要清除上一帧
    ax.barh(cur_df["name"], cur_df["value"], color=["r", "g"])
    for i, (name,value) in enumerate(zip(cur_df["name"], cur_df["value"])): # 设置右侧的值
        ax.text(value, i, name, ha="right")
        ax.text(value, i-0.25, value, ha="right")
    ax.text(1, 0.5, year, transform=ax.transAxes,  ha="right") # 设置年份
animator = animation.FuncAnimation(fig, draw_one_year, frames=range(2019, 2021)) # 动态绘制
animator.save("./test.gif") # 保存数据

在这里插入图片描述

简单例子

基本的操作大概这些,具体来看一个简单的例子吧

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
####这里是数据,为了降低难度,并未放在文件中####
df = pd.DataFrame([["man", 71527, 2019],
["man", 71351, 2018],
["man", 71137, 2017],
["man", 70815, 2016],
["man", 70414, 2015],
["man", 70079, 2014],
["man", 69728, 2013],
["man", 69395, 2012],
["man", 69068, 2011],
["man", 68748, 2010],
["woman", 65343, 2010],
["woman", 65667, 2011],
["woman", 66009, 2012],
["woman", 66344, 2013],
["woman", 66703, 2014],
["woman", 67048, 2015],
["woman", 67456, 2016],
["woman", 67871, 2017],
["woman", 68187, 2018],
["woman", 68478, 2019]], columns=["name", "value", "year"])
####这里是数据,为了降低难度,并未放在文件中####
fig, ax = plt.subplots() # 准备画板
def draw_one_year(year): # 绘制单帧
    cur_df = df[df["year"]==year].sort_values(by="value")
    ax.clear() # 需要清除上一帧
    ax.barh(cur_df["name"], cur_df["value"], color=["r", "g"])
    for i, (name,value) in enumerate(zip(cur_df["name"], cur_df["value"])): # 设置右侧的值
        ax.text(value, i, name, ha="right")
        ax.text(value, i-0.25, value, ha="right")
    ax.text(1, 0.5, year, transform=ax.transAxes,  ha="right")
animator = animation.FuncAnimation(fig, draw_one_year, frames=range(2010, 2020), interval=200) # 动态绘制, interval为时间间隔
animator.save("./中国人口变化.gif") # 保存数据

这样看来有点动态排名的意思了
在这里插入图片描述

复杂例子

首先附上这个图数据获取的代码

import json
import requests
import pandas as pd
id2name = {"8777800059299301": "以家人之名(TW)",  "9000000001179501": "三十而已(國際站TW)", "248797401": "二十不惑",
           "9000000001242801": "如此可爱的我们", "252449101": "隱秘的角落", "212447801": "爱情公寓5",
           "210631201": "大侠霍元甲", "207100801": "雪琉璃", "7722951969573801": "亲爱的药王大人第二季", "204905101": "远大前程"}
tables = []
for id, name in id2name.items():
    response = requests.get("https://uaa.if.iqiyi.com/video_index/v2/get_index_trend?album_id="+id+"&time_window=7")
    data = json.loads(response.text)
    for i in range(6):
        row = [name, data["details"][0]["data"][i], data["playtime"][i]]
        tables.append(row)
df = pd.DataFrame(tables, columns=["name", "value", "day"])
df.to_csv("./datas.csv", index=None)

再来看这个复杂的例子

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
df = pd.read_csv("./datas.csv")
fig, ax = plt.subplots() # 准备画板
def draw_one_year(dt): # 绘制单帧
    cur_df = df[df["dt"]==dt].sort_values(by="value")
    ax.clear() # 需要清除上一帧
    ax.barh(cur_df["name"], cur_df["value"], color=["C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9"])
    for i, (name,value) in enumerate(zip(cur_df["name"], cur_df["value"])): # 设置右侧的值
        ax.text(value, i, name, fontsize=10, ha="right")
        ax.text(value, i-0.25, value,fontsize=10,  ha="right")
    ax.text(1, 0.5, dt, fontsize=24,  transform=ax.transAxes,  ha="right")
animator = animation.FuncAnimation(fig, draw_one_year, frames=range(20200807, 20200812), interval=200) # 动态绘制, interval为时间间隔
animator.save("./近期电视剧爱奇艺指数排名.gif") # 保存数据

颜色我采用通配了,如果想更美观,可以自己挑选颜色;并调整一下字体、刻度这些细节。
在这里插入图片描述

完善细节

具体可以参考这篇文章

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import ticker
from pylab import mpl
import datetime
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
df = pd.read_csv("./iqiyi_datas.csv")
fig, ax = plt.subplots() # 准备画板
def draw_one_year(dt): # 绘制单帧
    cur_df = df[df["dt"]==dt].sort_values(by="value").head(10)
    ax.clear() # 需要清除上一帧
    ax.barh(cur_df["name"], cur_df["value"], color=["C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9"])
    for i, (name,value) in enumerate(zip(cur_df["name"], cur_df["value"])): # 设置右侧的值
        ax.text(value, i, name, fontsize=10, ha="right", va="bottom")
        ax.text(value, i-0.25, value,fontsize=10,  ha="right", va="center")
    ax.text(1, 0.5, dt, fontsize=24,  transform=ax.transAxes,  ha="right")
    # 设置顶部value刻度
    ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
    ax.xaxis.set_ticks_position('top')
    ax.tick_params(axis='x', colors='#777777', labelsize=12)
    # 取消底部value刻度
    ax.set_yticks([])
    # 添加竖直的刻度线
    ax.grid(which='major', axis='x', linestyle='--')
    # 取消外边框
    plt.box(False)
dt_list = [int((datetime.datetime.strptime("20200813", "%Y%m%d") - datetime.timedelta(days =i)).strftime("%Y%m%d"))  for i in range(6,1,-1)]
animator = animation.FuncAnimation(fig, draw_one_year, frames=dt_list, interval=200) # 动态绘制, interval为时间间隔
animator.save("./近期电视剧爱奇艺指数变化.gif") # 保存数据

在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐