Seaborn是一個很好用的python數(shù)據(jù)可視化包。匯總一下之前做數(shù)據(jù)可視化時的一些注意事項和技巧焕议。
為什么有的數(shù)據(jù)可視化給人感覺起來很好看很舒服别瞭,其實涉及到Seaborn的一些細節(jié)操作問題嗤瞎,這里收集了我所關(guān)注到的注意事項虹菲。
文章結(jié)構(gòu)如下:
- Seaborn依賴的數(shù)據(jù)結(jié)構(gòu)
- Matplotlib
- Heatplot
- Jointplot
- Violinplot
- 組合圖(plt.plot+sns.heatplot)
(1) 組合圖的框架
(2) 子圖配置——heatplot
(3) 子圖配置——ax.plot
(4) 其他
1. Seaborn依賴的數(shù)據(jù)結(jié)構(gòu)
在使用Seaborn之前霎褐,需要強調(diào)和注意的是Seaborn依賴的數(shù)據(jù)結(jié)構(gòu)。pandas的dataframe可以很方便地兼容Seaborn的數(shù)據(jù)輸入拍埠。下面簡單介紹從csv文件導(dǎo)入dataframe數(shù)據(jù)以及一些相關(guān)的處理:
import pandas as pd
dataframe = pd.read_csv(filedir, usecols=[colsname]) # read data from csv file
dataframe.drop()
dataframe.iloc[]
這里需要說明的是棉圈,對于dataframe數(shù)據(jù)胎围,習(xí)慣上提前給列命名,方便之后Seaborn的使用德召,當(dāng)然也可以在Seaborn中重新命名白魂。
2. Matplotlib
Matplotlib可以很好的兼容Seaborn,可以通過Matplotlib對圖片尺寸進行修改上岗、ticklable及title等編輯福荸、保存圖片以及多個Seaborn子圖的排列方式和尺寸進行編輯,同時肴掷,也可以實現(xiàn)Seaborn和Matplotlib共同作圖敬锐。
(1) 圖片尺寸
# 方法一
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize=(11, 9))
# 方法二
import pylab
pylab.rcParams['figure.figsize'] = (12.0,7.0) # 顯示大小
(2) 圖片標(biāo)注及字體大小
import matplotlib.pyplot as plt
plt.xticks(fontsize=13)
plt.yticks(fontsize=13)
plt.xlim([0,4000])
plt.legend(['line1,'line2','line3'],fontsize=17)
plt.xlabel('x',fontsize=17)
plt.ylabel('y',fontsize=17)
plt.title('title', fontsize=20)
(3) 保存圖片
plt.savefig(filename+".png",format='png', bbox_inches='tight', transparent=True)
3. Heatplot
cmap = sns.diverging_palette(220, 10, as_cmap=True)
rc = {'font.size': 15, 'xtick.labelsize': 15, 'ytick.labelsize': 15}
sns.set(rc=rc)
# Draw the heatmap with the mask and correct aspect ratio
heatplt = sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,
square=True, linewidths=.5, cbar_kws={"shrink": .5}, annot=True, fmt=".2f")
其中,cmap可以定制heatmap的顏色呆瞻,seaborn的heatmap當(dāng)中的fmt參數(shù)可以修改顯示數(shù)字的位數(shù)台夺,例如".2f"表示float類型保留小數(shù)點后兩位。
4. Jointplot
sns.jointplot(x=x, y=y, kind="hex",color='r')
5. Violinplot
vio = sns.violinplot(data=Error, orient="v",linewidth=0.6)
for i in range(4):
plt.vlines(1.5+2*(i), -0.35, 0.35, colors = "c", linestyles = "dashed")
6. 組合圖
很多時候在描述一個問題時需要對不同的圖進行組合以達到表現(xiàn)的目的栋烤,例如將plt的曲線圖和seaborn的heatplot組合起來谒养,并且橫軸相對應(yīng),標(biāo)注要清楚可見。
這個時候需要根據(jù)以下步驟有條不紊地對圖進行設(shè)置买窟。
(1) 組合圖的框架
首先確認你的圖片當(dāng)中包含幾塊丰泊,例如如果包含兩塊,那么分別的尺寸以及比例是怎樣的始绍。
fig = plt.figure(figsize=(xSize, ySize))
gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1])
比如瞳购,如上代碼是做了一個兩行一列的結(jié)構(gòu),并且縱向比例是3:1亏推,整個圖片的大小是(xSize, ySize)学赛。
ax0 = plt.subplot(gs[0])
ax1 = plt.subplot(gs[1])
而subplot使用了gs為參數(shù),確定了子圖的句柄吞杭,可以通過對ax0或者ax1進行操作盏浇,以達到不同位置顯示不同的圖像的目的。
(2) 子圖配置——heatplot
在子圖當(dāng)中芽狗,我們首先對heatplot進行操作绢掰,
heatplt = sns.heatmap(data, linewidths=0, ax=ax1, cmap="YlGnBu", annot=False,
yticklabels=['data'], xticklabels=xtick,
cbar=False)
注意點-1:
因為考慮到需要將heatplot的橫軸與plt的曲線圖橫軸對齊,所以關(guān)閉圖例顯示童擎,當(dāng)然也可以將圖例與橫軸平行放置滴劲,但是為了美觀,這里我關(guān)掉了cbar的顯示顾复。
注意點-2:
對于橫軸較為密集的情況下班挖,例如是一個很長的時間段,需要對橫軸進行間隔標(biāo)注顯示芯砸,這樣給人看起來很清楚萧芙,不會因為密密麻麻擠在一起導(dǎo)致看不清的問題。所以使用如下的配置:
import matplotlib.ticker as ticker
ax1.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
tick_spacing是可以修改的參數(shù)乙嘀,顧名思義末购,是標(biāo)注間隔的意思破喻,這里需要注意虎谢,tick_spacing需要和給定的標(biāo)注序列統(tǒng)一,舉個例子曹质,比如現(xiàn)在需要給橫軸標(biāo)注1到100婴噩,共100個數(shù)字,但是由于太過密集羽德,需要用到tick_spacing參數(shù)進行稀疏標(biāo)注几莽,那么在給heatplot的xticklabels傳遞參數(shù)時,就必須根據(jù)tick_spacing對序列進行系數(shù)處理宅静,親測如下代碼無誤:(僅限配置heatplot)
SliceStart = 0
SliceEnd = len(data)
tick_spacing = 10
xtick=range(SliceStart - tick_spacing, SliceEnd, tick_spacing)
需要注意的是必須減去tick_spacing章蚣,否則標(biāo)注會錯位。
(3) 子圖配置——ax.plot
這里是曲線圖部分姨夹,不做過多描述纤垂,有一點需要注意的就是矾策,因為兩個子圖共用一個橫坐標(biāo),所以第一行的圖(也就是plot)的橫坐標(biāo)標(biāo)注可以隱藏不顯示峭沦,通過如下代碼實現(xiàn):
plt.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labelbottom=False) # labels along the bottom edge are off
(4) 其他
為了確保兩個圖的橫坐標(biāo)對齊贾虽,每個子圖配置結(jié)束后添加一行。
plt.xlim([0, LenData])
(5) 代碼
from matplotlib import gridspec
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import pandas as pd
import numpy
from pandas import Series
def drawHeat_plot(line, data, xSize, ySize, xtick, tick_spacing, cols='sin',
filename='HeatPlot', title='Demo',
yticklabel=['Value']):
textFS = 80
titleFS = 100
LenData = len(line)
rc = {'font.size': textFS, 'xtick.labelsize': textFS, 'ytick.labelsize': textFS, }
sns.set(rc=rc)
size = np.shape(data)
fig = plt.figure(figsize=(xSize, ySize))
gs = gridspec.GridSpec(2, 1, height_ratios=[2, 1])
ax1 = plt.subplot(gs[1])
heatplt = sns.heatmap(data, linewidths=0, ax=ax1, cmap="YlGnBu", annot=False,
xticklabels=xtick,
cbar=False, yticklabels=yticklabel)
plt.xticks(fontsize=textFS)
plt.yticks(fontsize=textFS)
ax1.set_ylabel('Value', fontsize=textFS)
ax1.set_xlabel('Time step', fontsize=textFS)
plt.xlim([0, LenData])
ax1.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
ax0 = plt.subplot(gs[0])
ax0.plot(line, linewidth=3)
ax0.set_ylabel('Value', fontsize=textFS)
plt.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labelbottom=False) # labels along the bottom edge are off
ax0.set_title(title, fontsize=titleFS)
ax0.grid(linestyle='--', linewidth='0.5', color='black')
plt.legend([cols + ' Data'], fontsize=textFS)
plt.xlim([0, LenData])
fig = heatplt.get_figure()
fig.savefig(filename + ".png", format='png', bbox_inches='tight', transparent=True)
Demo數(shù)據(jù)及參數(shù):
line = np.sin([3.14*i/20 for i in range(0,100)])
data = np.sin([3.14*i/20 for i in range(0,100)])
line = np.reshape(line,[100,])
data = np.reshape(data,[1,100])
xSize = 150
ySize = 30
SliceStart = 0
SliceEnd = 100
TickSpace = 10
運行代碼:
drawHeat_plot(line, data, xSize, ySize, range(SliceStart - TickSpace, SliceEnd, TickSpace), tick_spacing=TickSpace, cols='sin',
filename='HeatPlot', title='Demo')
運行結(jié)果:
總結(jié):
數(shù)據(jù)可視化是一門學(xué)問吼鱼,如何在一張有限的圖上清楚有效地展示圖片想要說明的信息蓬豁。一方面,根據(jù)想要突出數(shù)據(jù)的哪方面的信息菇肃,選擇合適類型的圖型地粪;另一方面,給讀圖的人一種清楚明了的感覺琐谤,需要對可視化圖的細節(jié)——例如排布驶忌、字體、字體大小笑跛、圖例付魔、顏色等等各個方面進行調(diào)節(jié)。這樣飞蹂,做出figure才既能表達作圖者想要表達的信息几苍,也能讓讀圖者清楚清爽地領(lǐng)會數(shù)據(jù)呈現(xiàn)出來的信息。
之后筆者接觸到其他類型的可視化以及相關(guān)注意事項時會繼續(xù)在這篇文章中書寫陈哑。如有意見和建議請各位提出~