使用seaborn绘制强化学习中的图片问题

 更新时间:2023年01月31日 10:29:28   作者:johnjim0816  
这篇文章主要介绍了使用seaborn绘制强化学习中的图片问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

seaborn绘制强化学习中的图片

seaborn可以说是matplotlib的升级版,使用seaborn绘制折线图时参数数据可以传递ndarray或者pandas,方便又好看!

本篇用绘制强化学习中的rewards举例,实际上也可以用来机器学习中的loss曲线,原理类似。

从一个简单示例开始

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns # 导入模块
sns.set() # 设置美化参数,一般默认就好

rewards = np.array([0, 0.1,0,0.2,0.4,0.5,0.6,0.9,0.9,0.9])
plt.plot(rewards)
plt.show()

如上首先导入seaborn模块,并设置美化参数(aesthetic parameters)sns.set(),使用matplotlib.pyplot as plt就可以绘制一个基本的图像:

使用sns.lineplot或者sns.relplot

实际上relplot包含lineplot和scatterplot,并通过kind传参可以转换为lineplot,

relplot(kind="line")等价于lineplot
relplot(kind="scatter")等价于scatterplot

然后再进行适当的调整并加上x,y轴的label,如下:

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns; sns.set() # 因为sns.set()一般不用改,可以在导入模块时顺便设置好

rewards = np.array([0, 0.1,0,0.2,0.4,0.5,0.6,0.9,0.9,0.9])
sns.lineplot(x=range(len(rewards)),y=rewards)
# sns.relplot(x=range(len(rewards)),y=rewards,kind="line") # 与上面一行等价
plt.xlabel("episode")
plt.ylabel("reward")
plt.show()

最后呈现效果如下:

绘制rewards聚合图

当我们对同一实验作出多次得到一组rewards时,如下:

rewards1 = np.array([0, 0.1,0,0.2,0.4,0.5,0.6,0.9,0.9,0.9])
rewards2 = np.array([0, 0,0.1,0.4,0.5,0.5,0.55,0.8,0.9,1])
rewards=np.vstack((rewards1,rewards2)) # 合并成二维数组

我们希望绘制出聚合图,但是sns.lineplot无法输入一维以上的数据,我们可以将它们全部转为一维,虽然有些难看:

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns; sns.set() # 因为sns.set()一般不用改,可以在导入模块时顺便设置好

rewards1 = np.array([0, 0.1,0,0.2,0.4,0.5,0.6,0.9,0.9,0.9])
rewards2 = np.array([0, 0,0.1,0.4,0.5,0.5,0.55,0.8,0.9,1])
rewards=np.concatenate((rewards1,rewards2)) # 合并数组
episode1=range(len(rewards1))
episode2=range(len(rewards2))
episode=np.concatenate((episode1,episode2))
sns.lineplot(x=episode,y=rewards)
plt.xlabel("episode")
plt.ylabel("reward")
plt.show()

结果如图:

绘制出了带聚合阴影的图,实际上实际部分是seaborn默认对同一x轴的多个y值即rewards做了均值,阴影部分表示多组rewards的范围,可以使用sns.lineplot(x=episode,y=rewards,ci=None)去掉。

使用pandas传参

上面都是用ndarray传参,这样一方面免不了与matplotlib.pyplot混杂的成分比如plt.xlabel,另外绘制rewards聚合图,也比较麻烦。

既然使用pandas传参,就需要先把array转成DataFrame形式,如下:

import numpy as np
import pandas as pd
rewards1 = np.array([0, 0.1,0,0.2,0.4,0.5,0.6,0.9,0.9,0.9])
rewards2 = np.array([0, 0,0.1,0.4,0.5,0.5,0.55,0.8,0.9,1])
rewards=np.vstack((rewards1,rewards2)) # 合并数组
df = pd.DataFrame(rewards).melt(var_name='episode',value_name='reward') # 推荐这种转换方法
print(df)

推荐上述转化方法,这样无论rewards多少维都不影响最终的绘图方式,其中melt方法将所有维合并成一列,var_name='episode',value_name='reward'则更改对应的列名,转化结果如下:

   episode  reward
0        0     0.0
1        0     0.1
2        0     0.0
3        0     0.2
4        0     0.4
5        0     0.5
6        0     0.6
7        0     0.9
8        0     0.9
9        0     0.9

下面完整绘图:

import seaborn as sns;sns.set()
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

import pandas as pd
rewards1 = np.array([0, 0.1,0,0.2,0.4,0.5,0.6,0.9,0.9,0.9])
rewards2 = np.array([0, 0,0.1,0.4,0.5,0.5,0.55,0.8,0.9,1])
rewards=np.vstack((rewards1,rewards2)) # 合并数组
df = pd.DataFrame(rewards).melt(var_name='episode',value_name='reward')

sns.lineplot(x="episode", y="reward", data=df)
plt.show()

注意这里的x,y不再传入数组,而是传入DataFrame中对应的列名,类似于python字典中的键

结果如下:

牛刀小试

最后绘制一个更为复杂的可以用于paper的绘制方法:

import seaborn as sns; sns.set()
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

def get_data():
    '''获取数据
    '''
    basecond = np.array([[18, 20, 19, 18, 13, 4, 1],[20, 17, 12, 9, 3, 0, 0],[20, 20, 20, 12, 5, 3, 0]])
    cond1 = np.array([[18, 19, 18, 19, 20, 15, 14],[19, 20, 18, 16, 20, 15, 9],[19, 20, 20, 20, 17, 10, 0]]) 
    cond2 = np.array([[20, 20, 20, 20, 19, 17, 4],[20, 20, 20, 20, 20, 19, 7],[19, 20, 20, 19, 19, 15, 2]]) 
    cond3 = np.array([[20, 20, 20, 20, 19, 17, 12],[18, 20, 19, 18, 13, 4, 1], [20, 19, 18, 17, 13, 2, 0]])    
    return basecond, cond1, cond2, cond3
    
data = get_data()
label = ['algo1', 'algo2', 'algo3', 'algo4']
df=[]
for i in range(len(data)):
    df.append(pd.DataFrame(data[i]).melt(var_name='episode',value_name='loss'))
    df[i]['algo']= label[i] 

df=pd.concat(df) # 合并
sns.lineplot(x="episode", y="loss", hue="algo", style="algo",data=df)
plt.title("some loss")
plt.show()

结果如下:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Python中的装饰器类详解

    Python中的装饰器类详解

    Python 装饰器在很多情况下是一个非常有用的工具,它们可以用于修改或增强函数或类的行为,本篇文章将深入探讨如何在 Python 中使用类装饰器
    2023-06-06
  • Python的Django中将文件上传至七牛云存储的代码分享

    Python的Django中将文件上传至七牛云存储的代码分享

    七牛云存储可以帮助服务器转存图片等数据,类似于Dropbox等存储服务,这里就带给大家Python的Django中将文件上传至七牛云存储的代码分享,需要的朋友可以参考下
    2016-06-06
  • 详解Pymongo常用查询方法总结

    详解Pymongo常用查询方法总结

    这篇文章主要介绍了详解Pymongo常用查询方法总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • python如何创建TCP服务端和客户端

    python如何创建TCP服务端和客户端

    这篇文章主要为大家详细介绍了python如何创建TCP服务端和客户端,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • Python实现Smtplib发送带有各种附件的邮件实例

    Python实现Smtplib发送带有各种附件的邮件实例

    本篇文章主要介绍了Python实现Smtplib发送带有各种附件的邮件实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • python生成随机图形验证码详解

    python生成随机图形验证码详解

    这篇文章主要介绍了python生成随机图形验证码详解,具有一定参考价值,需要的朋友可以参阅。
    2017-11-11
  • python高阶爬虫实战分析

    python高阶爬虫实战分析

    这篇文章给大家分享了python高阶爬虫实战的相关实例内容以及技巧分析,有兴趣的朋友参考下。
    2018-07-07
  • Python基于Faker假数据构造库

    Python基于Faker假数据构造库

    这篇文章主要介绍了Python基于Faker假数据构造库,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • python 如何用terminal输入参数

    python 如何用terminal输入参数

    这篇文章主要介绍了python 如何用terminal输入参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • numpy数组广播的机制

    numpy数组广播的机制

    这篇文章主要介绍了numpy数组广播的机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07

最新评论