使用Matplotlib绘制多分类概率动态柱状图

在用LSTM做人类行为识别的时候,想用matplotlib生成概率预测的柱状图,这方面可参考的资料比较少,基本上都是在绘制折线图,不能满足要求。于是参考Matplotlib Animation Tutorial动态排名柱状图程序,完成了分类概率输出的动态柱状图功能,现将整个流程总结如下,有相似需求的小伙伴,可以根据自己的项目要求相应修改。使用Animation类,需要安装ffmpeg或者imagemagick。

第一步导入keras训练保存的模型:

from keras.models import load_model
model = load_model('my_model.h5')

第二步准备输入数据:
因为做人类行为识别,所以输入时传感器数据,因此用pandas的read_csv()方法,将UCI-HAR数据集中的.txt格式转化为pandas的DataFrame数据结构。

# 定义读取数据函数,转换为DataFrame数据结构,返回Numpy数组。
def load_file(name,filepath):
    dataframe = pd.read_csv(filepath + name, header=None, delim_whitespace=True)
    return dataframe.values

# 定义 pandas读取 UCI HAR 数据集中的所有数据的函数;
# 数组的维数为 [样本,时间步长,特征]([sample,timestamp,features])
# numpy 的 dstack()方法将输入数据按照第三维堆叠。
def load_group(filenames,filepath):
    loaded = list()
    for name in filenames:
        data = load_file(name,filepath)
        loaded.append(data)
    # stack group so that features are the 3rd dimension
    loaded = np.dstack(loaded)
    return loaded

# 因为UCI-HAR数据集将六轴的传感器合三轴的重力加速度信息信息分成了九个不同的txt文本,所以需要全部导入。
# 读取数据文件所在根目录中所有文件,并将文件名添加到列表file_lists
filepath = 'D:/Code/Datasets/UCIHAR/test/InertialSignals/'
y_label_path = 'D:/Code/Datasets/UCIHAR/test/'
file_lists = []
for parents,dirnames,filenames in os.walk(filepath):
    for filename in filenames:
        file_lists.append(filename)
print(file_lists)

# 加载测试集输入数据
X = load_group(file_lists,filepath)
# 加载测试集的分类标记,这个文件是1-6数字,表示六类。
y = load_file('y_test.txt',y_label_path)

# 加载测试数据集
testX, testy = X, y
print(testX.shape, testy.shape)
# 减去1以保证one-hot编码后的分类数为6
testy = testy - 1
# 使用keras的方法对分类进行one-hot编码
testy = to_categorical(testy)

print(testX.shape, testy.shape)

第三步模型预测

# predict返回每一个测试样本的各个分类概率
y_predict_list = model.predict(testX) #(2947, 6)
# 生成分类标签
y_pred = model.predict_classes(testX) #(2947, 1)

#转换为DataFrame
df_pred_pro = pd.DataFrame(y_predict_list)
# 修改列标题
df_pred_pro.rename(columns={0:'Walking',1:'Walking-upstairs',2:'Walking-downstairs',3:'Sitting',4:'Standing',5:'Laying'},inplace=True)

df_pred_pro 最终输出
在这里插入图片描述
第四步绘制动态柱状图:

from matplotlib.animation import FuncAnimation
#保证动图以弹出显示,后端为qt5
#%matplotlib qt5
import time

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['Microsoft JhengHei']
plt.rcParams['axes.unicode_minus'] = False

plugins = ['Walking','Walking-upstairs','Walking-downstairs','Sitting','Standing','Laying']
fig, ax = plt.subplots(figsize=(20,8))
# 分配颜色的字典
# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
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))}

frame = 20

# 设置更新函数,i为帧的ID,这样就能一帧一帧的更新图像。
def update(i):
    print(i)

    df_ = df_pred_pro
    names = df_.iloc[i,:].index
    colors = [plugin_color[name] for name in names]
    value = df_.iloc[i,:].values
    ax.clear()
    rects = ax.bar(x=names,height=value,width=0.8,align='center',color=colors)
    # 设置y轴刻度
    ax.set_yticks(np.arange(0,1.1,0.05))
    # 添加x、y轴描述信息和标题
    ax.set_xlabel('预测类别',color='black',size=15)
    ax.set_ylabel('概率', color='black',size=15)
    ax.set_title('模型概率预测 timestamp:{}'.format(i*64),color='blue',size=20)
    # 添加网格显示
    ax.grid(linestyle='--',alpha=0.5)
    
    # 每个柱的数字标签
    for i_, v in enumerate(value):
        ax.text(i_-0.06, v + 0.02, '%.5f%%'%(v*100), color=colors[i_])
        #ax.text(3, 1.1, 128+i_*64, fontweight='bold', fontsize='25', color='red')        
    
    return rects

ani = FuncAnimation(fig=fig, # 更新的画布
                    func=update, # 更新函数
                    frames=1000, # 生成动态图的帧数
                    interval=100,  # 帧间时间间隔,单位:ms
                    blit=True, # 让输出显示更快
                    repeat=False # 不循环播放
                    )

ani.save('test.mp4',  # 文件名称
		fps=10, #保存的视频帧率
		extra_args=['-vcodec', 'libx264']) # x264解码规则,以支持HTML5视频格式。
# ani.save('test.gif', writer='ffmpeg')
# %matplotlib in line
# from IPython.display import HTML
# HTML(ani.to_html5_video())
#plt.show()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

datamonday

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值