受B站拜年祭发射最多的弹幕是什么?视频启发,对日常维护工作中的故障硬件也做了一次盘点。这里介绍两种方法,第一种是Python + Matplotlib;第二种是利用GitHub上现成的“轮子”。如果需要快速出图,后者更简单(也更美观)。

方法一:Python

MATPLOTLIB的动画类

MATPLOTLIB包含了一个动画类——Animation,用这个类就可以实现图标的动画效果。先看下官方文档给出的例子:

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()xdata, ydata = [], []ln, = plt.plot([], [], 'ro')

def init():

ax.set_xlim(0, 2*np.pi)

ax.set_ylim(-1, 1)

return ln,

def update(frame):

xdata.append(frame)

ydata.append(np.sin(frame))

ln.set_data(xdata, ydata)

return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),

init_func=init, blit=True)plt.show()

上例中,init初始化图表,update函数则负责更新图表中的数据。最主要的是FuncAnimation,通过不断调用update,并将frames参数中的值依次传递给update,更新图表。这个例子的运行结果如下:

示例gif

数据整理

先将故障硬件的名称、故障数量和发生日期整理好。好在这些数据一直以来都有不定期梳理。梳理后的格式如下:

整理后的数据

保存成csv后由pandas读取到DataFrame中,同时解析日期:

with open('plugin_faults.csv', 'r') as f:

data = pd.read_csv(f, parse_dates=['date'])

因为柱状图中每根柱的长度是个累计值,而表中的是当天故障的数量,因此要按故障硬件名称累积求和:

data = data.sort_values('date')

group = data.groupby('name')

data['value_cumsum'] = group.cumsum()

data.sort_values(['date','value_cumsum','name'], inplace=True)

data.drop_duplicates(['date','name'], keep='last', inplace=True)

填充所有日期,所有硬件类型

plugins = ['PCU', '电源板', 'AS7-D', 'ESB24-D', 'CPU', 'HWAT-B', 'SW256B', 'SWPRO-C',

'ETP', 'ET16', '时钟板', 'DRAM', 'TR3T', '硬盘', 'HDSAM-A', 'DCAR1-A', '光模块', '熔丝', '网管交换机'] # 所有硬件名称

start = datetime(2017,1,1) # 开始日期

end = datetime(2019,12,31) # 结束日期

dates = [start + timedelta(days=i) for i in range((end - start).days + 1)]

index = pd.MultiIndex.from_product([dates, plugins], names = ["date", "name"]) # 3年内所有日期与硬件名称的笛卡尔积作为多重索引

df = pd.DataFrame(index=index)

df['value'] = data.set_index(['date', 'name'])['value_cumsum'] # 向DataFrame填入data中的数据

df = df.unstack(level=1).fillna(method='ffill') # 将硬件名称索引unstack,前向填充累计故障数(比如累计到昨天一共坏n件,而今天没有该硬件故障,则累计数量还是n件)

df = df.stack(dropna=False).reset_index().fillna(0) # 转换成无索引的DataFrame,并填充缺失值为0(从开始时间直至第一个同类型硬件发生故障的值均为缺失值)

至此数据整理部分结束,得到了2017至2019年共计3年内每天每种硬件故障的累计数的DataFrame。

作图

通过水平柱状图将故障硬件的数量进行排名可视化,每个柱一个颜色,由多到少自上往下排列。

水平柱状图用barh生成,动画需更新每日的排序,但同一种硬件的颜色不能改变,因此初始化了plugin_color字典。

update函数中的df_i为当前帧所使用的数据,以日期作为筛选标准。

fig, ax = plt.subplots()

# 分配颜色的字典

colormap = [i / len(plugins) * 0.7 + 0.15 for i, _ in enumerate(plugins)]

colormap = plt.get_cmap('Paired')(colormap)

plugin_color = {plugins[i]: colormap[i] for i in range(len(plugins))}

def update(i):

date = datetime(2017, 1, 1) + timedelta(days=i)

# 筛选当日的数据,按数量排序

df_i = df[df['date'] == date]

df_i = df_i.sort_values('value', ascending=True)

names = df_i['name'] # 硬件名称作为Y轴标签

colors = [plugin_color[name] for name in names]

value = df_i['value'] # X轴的值

ax.clear() # 清理ax,否则排序不会重做

x = max(value) * 0.85 # 图中日期标签的水平相对位置

if i == 0:

ax.set_xlim(0, 1.05)

x = 0.85

# 水平柱状图

rects = ax.barh(y=names,

width=value,

align='center',

height=0.5,

color=colors)

# 每个柱的数字标签

for i, v in enumerate(value):

ax.text(v + 0.1, i, int(v), color=colors[i], ha='left', va='center')

# 日期标签

ax.text(x, 0.5, date.strftime('%Y-%m-%d'),

fontweight='bold', fontsize='25', color='red')

return rects

生成动画对象,回调函数为update,frames传入3年的日期数,interval定义每一帧的时延(每秒8帧)。

blit我试了下没感觉有啥区别,按照官方文档的说法,是一种比较老的绘图技术,这里设成False。

repeat控制是否循环播放。

ani = animation.FuncAnimation(fig=fig,

func=update,

frames=int(len(df) / len(plugins)),

interval=1000/8, # 每帧之间的时延,单位:ms

blit=False,

repeat=False)

保存为视频或GIF:

ani.save('test.gif', dpi=10, writer='pillow')

ani.save('test.mp4')

如果要在jupyter notebook中直接显示(中文显示问题参见“参考3”):

%matplotlib inline

from IPython.display import HTML

HTML(ani.to_html5_video())

生成的动态排名柱状图GIF(完整的GIF太大,只截部分):

生成gif

方法二:现成的“轮子”

从ID来看,应该就是B站视频的原作者在GitHub上的一个库(见“参考2”),使用的是d3.js的前端作图。只要将数据整理成规定的格式,直接从网页导入即可。也可以修改一些简单的配置,非常好用,在此推荐一下。

最后一帧截图:

最后一帧

参考

python动态柱状图_动态排名柱状图的两种做法相关推荐

  1. 运用Python爬取二手房价格与信息的两种常用方法

    最近房地产市场进一步收紧,多地地方政府出台各种收紧政策,以保证房地产健康发展,因此云朵君就想到运用Python网络爬虫,抓取部分房产信息,了解下最近房地产的情况. 接下来以房天下二手房信息,以获取某个 ...

  2. Python计算程序运行时间秒级/毫秒级的两种方法datetime和time

    Python计算程序运行时间秒级/毫秒级的两种方法datetime和time 简单粗暴,先上代码: import datetime import time# 方法一:datetime.datetime ...

  3. python 数组 动态赋值_动态数组在Python中的实现

    动态数组 在python中,列表,集合和字典是可变对象.数字,字符串和元组是不可变的对象.可变对象意味着我们从列表,集合或字典中添加/删除项目,但是对于不可变对象(例如元组或字符串)而言,情况并非如此 ...

  4. mysql动态扩展_动态可扩展查询MYSQL5.7JSON+虚拟列+Mybatis

    背景:现有业务扩展字段,都存在feature字段,存在语义不清晰以及,难以利用索引查询问题 Mysql 5.7后推出利器,JSON+虚拟列,即实现了业务语义统一,也支持索引查询加速 一.简单描述 My ...

  5. 动态路由协议_动态路由协议的类别

    动态路由协议 Dynamic routing protocols have been divided into 2 categories i.e Distance vector protocols a ...

  6. python 字符串拼接_面试官让用 3 种 python 方法实现字符串拼接 ?对不起我有8种……...

    点击上方 蓝字关注我们 点击上方"印象python",选择"星标"公众号重磅干货,第一时间送达!之前发过很多关于 Python 学习的文章,收到大家不少的好评, ...

  7. android的动态注册,Android JNI 函数注册的两种方式(静态注册/动态注册)

    JNI/NDK 在Android开发中,由于种种原因我们需要调用C/C++代码, 这个时候就要用到Android开发者都听说过的JNI(Java Native Interface)了, 在调用JNI相 ...

  8. python 命名实体识别_命名实体识别的两种方法

    作者:Walker 目录 一.什么是命名实体识别 二.基于NLTK的命名实体识别 三.基于Stanford的NER 四.总结 一 .什么是命名实体识别? 命名实体识别(Named Entity Rec ...

  9. python import sql脚本_13-模块介绍-import两种方式-py文件的两种用途-模块搜索路径-项目开发的目录规范...

    1.模块的介绍与使用模块import 1.1.模块的介绍 1.1.1.什么是模块? 模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能.在python中,模块的使用方式都是一样的,但其 ...

最新文章

  1. Springboot-读取核心配置文件及自定义配置文件
  2. 【练习】不同排序算法执行时间比较
  3. 个人博客系统的设计与实现_一款小而美的博客系统,专为程序员设计
  4. 数学--数论--HDU 2104 丢手绢(离散数学 mod N+ 剩余类 生成元)+(最大公约数)
  5. dotnet core 微服务教程
  6. linux history原理,linux history(命令历史)
  7. Alfresco支持LDAP验证
  8. 对JMETER组件的认知
  9. Linux之du命令
  10. 【ABAP系列】SAP DOI技术中I_OI_SPREADSHEET接口的使用
  11. JEB2.2.7闪退
  12. win7资源服务器未响应,win7电脑怎么设置服务器未响应
  13. Windows11如何使用安卓子系统的Amazon Appstore
  14. 有道云笔记中轻松驾驭职场框架图
  15. OpenGL Android课程六:介绍纹理过滤
  16. 富瑞和SMBC Group宣布结成战略联盟来推动增长
  17. 每日新闻:腾讯与Line携手在日本提供移动支付服务;阿里组织架构调整 行癫任阿里云智能总裁;每周要工作80小时才有可能改变世界...
  18. linux中dd命令增加内存使用率,Linux 下使用 dd 命令进行硬盘 I/O 性能检测
  19. ps批量修改图片大小
  20. 玩转手机中的linux系统termux并搭建java开发环境

热门文章

  1. AD之PCB各层说明
  2. 数据库系统概论-005: 数据库完整性(正确性和相容性)
  3. Python新型冠状病毒疫情数据自动爬取+统计+发送报告+数据屏幕(二)统计篇
  4. vostro3070装win7_戴尔Vostro 成就 3070台式机装win7系统及bios设置
  5. 大话西游java正版_大话西游网易正版电脑版
  6. Bison 的构成与使用
  7. 工程流体力学笔记暂记16(欧拉积分和伯努利积分)
  8. 带你修改电脑用户名从中文到英文
  9. Hive之窗口函数(partition) / order by / row_number / date_sub 等函数联合使用案例(9)
  10. 博后招募 | 山东大学闵哲教授招聘智能手术机器人与医学图像处理方向博士后...