使用seaborn繪制強(qiáng)化學(xué)習(xí)中的圖片問(wèn)題
seaborn繪制強(qiáng)化學(xué)習(xí)中的圖片
seaborn可以說(shuō)是matplotlib的升級(jí)版,使用seaborn繪制折線圖時(shí)參數(shù)數(shù)據(jù)可以傳遞ndarray或者pandas,方便又好看!
本篇用繪制強(qiáng)化學(xué)習(xí)中的rewards舉例,實(shí)際上也可以用來(lái)機(jī)器學(xué)習(xí)中的loss曲線,原理類(lèi)似。
從一個(gè)簡(jiǎn)單示例開(kāi)始
import matplotlib.pyplot as plt import numpy as np import seaborn as sns # 導(dǎo)入模塊 sns.set() # 設(shè)置美化參數(shù),一般默認(rèn)就好 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()
如上首先導(dǎo)入seaborn模塊,并設(shè)置美化參數(shù)(aesthetic parameters)sns.set()
,使用matplotlib.pyplot as plt
就可以繪制一個(gè)基本的圖像:
使用sns.lineplot或者sns.relplot
實(shí)際上relplot包含lineplot和scatterplot,并通過(guò)kind
傳參可以轉(zhuǎn)換為lineplot,
relplot(kind="line")等價(jià)于lineplot relplot(kind="scatter")等價(jià)于scatterplot
然后再進(jìn)行適當(dāng)?shù)恼{(diào)整并加上x(chóng),y軸的label,如下:
import matplotlib.pyplot as plt import numpy as np import seaborn as sns; sns.set() # 因?yàn)閟ns.set()一般不用改,可以在導(dǎo)入模塊時(shí)順便設(shè)置好 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") # 與上面一行等價(jià) plt.xlabel("episode") plt.ylabel("reward") plt.show()
最后呈現(xiàn)效果如下:
繪制rewards聚合圖
當(dāng)我們對(duì)同一實(shí)驗(yàn)作出多次得到一組rewards時(shí),如下:
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)) # 合并成二維數(shù)組
我們希望繪制出聚合圖,但是sns.lineplot
無(wú)法輸入一維以上的數(shù)據(jù),我們可以將它們?nèi)哭D(zhuǎn)為一維,雖然有些難看:
import matplotlib.pyplot as plt import numpy as np import seaborn as sns; sns.set() # 因?yàn)閟ns.set()一般不用改,可以在導(dǎo)入模塊時(shí)順便設(shè)置好 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)) # 合并數(shù)組 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()
結(jié)果如圖:
繪制出了帶聚合陰影的圖,實(shí)際上實(shí)際部分是seaborn默認(rèn)對(duì)同一x軸的多個(gè)y值即rewards做了均值,陰影部分表示多組rewards的范圍,可以使用sns.lineplot(x=episode,y=rewards,ci=None)
去掉。
使用pandas傳參
上面都是用ndarray傳參,這樣一方面免不了與matplotlib.pyplot
混雜的成分比如plt.xlabel,另外繪制rewards聚合圖,也比較麻煩。
既然使用pandas傳參,就需要先把a(bǔ)rray轉(zhuǎn)成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)) # 合并數(shù)組 df = pd.DataFrame(rewards).melt(var_name='episode',value_name='reward') # 推薦這種轉(zhuǎn)換方法 print(df)
推薦上述轉(zhuǎn)化方法,這樣無(wú)論rewards
多少維都不影響最終的繪圖方式,其中melt
方法將所有維合并成一列,var_name='episode',value_name='reward'
則更改對(duì)應(yīng)的列名,轉(zhuǎn)化結(jié)果如下:
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)) # 合并數(shù)組 df = pd.DataFrame(rewards).melt(var_name='episode',value_name='reward') sns.lineplot(x="episode", y="reward", data=df) plt.show()
注意這里的x,y不再傳入數(shù)組,而是傳入DataFrame中對(duì)應(yīng)的列名,類(lèi)似于python字典中的鍵
結(jié)果如下:
牛刀小試
最后繪制一個(gè)更為復(fù)雜的可以用于paper的繪制方法:
import seaborn as sns; sns.set() import matplotlib.pyplot as plt import numpy as np import pandas as pd def get_data(): '''獲取數(shù)據(jù) ''' 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()
結(jié)果如下:
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
jupyter notebook指定啟動(dòng)目錄的方法
這篇文章主要介紹了jupyter notebook指定啟動(dòng)目錄的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03python 時(shí)間信息“2018-02-04 18:23:35“ 解析成字典形式的結(jié)果代碼詳解
本文是類(lèi)方法給大家介紹如何將python 時(shí)間信息“2018-02-04 18:23:35“ 解析成字典形式的結(jié)果,需要的朋友可以參考下2018-04-04深入分析python數(shù)據(jù)挖掘 Json結(jié)構(gòu)分析
這篇文章通過(guò)實(shí)例給大家分析總結(jié)了python數(shù)據(jù)挖掘以及Json結(jié)構(gòu)分析的相關(guān)知識(shí)點(diǎn),對(duì)此有興趣的朋友參考下。2018-04-04python動(dòng)態(tài)監(jiān)控日志內(nèi)容的示例
本文介紹如何使用Python動(dòng)態(tài)監(jiān)控程序日志的內(nèi)容,這里的動(dòng)態(tài)指的是日志文件不斷的追加新的日志內(nèi)容,動(dòng)態(tài)監(jiān)控是指監(jiān)控日志新追加的日志內(nèi)容2014-02-02如何用Anaconda搭建虛擬環(huán)境并創(chuàng)建Django項(xiàng)目
在本篇文章里小編給大家整理了關(guān)于如何用Anaconda搭建虛擬環(huán)境并創(chuàng)建Django項(xiàng)目的相關(guān)文章,需要的朋友們可以跟著學(xué)習(xí)下。2020-08-08淺析python中numpy包中的argsort函數(shù)的使用
這篇文章主要介紹了python中numpy包中的argsort函數(shù)的使用,argsort()函數(shù)在模塊numpy.core.fromnumeric中,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2018-08-08