可視化技能之Matplotlib(上)|可視化系列01

? ???作者:蜇蟲適航
? ? ?來源:蜇蟲適航
Matplotlib可以說是Python最聲名遠(yuǎn)揚(yáng)的可視化庫了,也是Python數(shù)據(jù)分析庫的“三駕馬車”之一。Matplotlib是基礎(chǔ)而非常強(qiáng)大的可視化庫,Seaborn等好用的可視化庫是在前者的基礎(chǔ)上進(jìn)行的封裝。Matplotlib擅長快速出簡單的圖、有豐富的接口進(jìn)行精細(xì)化繪圖、和Numpy結(jié)合做科學(xué)可視化及三維圖配合默契、三維圖。但也有些缺點(diǎn),如不容易基于實(shí)用目的繪制有一定難度的圖表(如小提琴圖等)、標(biāo)簽等元素需指定坐標(biāo)而不能自適應(yīng)優(yōu)化顯示、難以實(shí)現(xiàn)交互。
官網(wǎng)[1]說:
Matplotlib tries to make easy things easy and hard things possible.
越用越認(rèn)可這句話,Matplotlib非常強(qiáng)大,Hard things是possible但并非easy and fast。
可視化基礎(chǔ)框架
對于一個(gè)數(shù)據(jù)表df(通過pandas讀入為DataFrame)來說,用Matplotlib對其進(jìn)行可視化的基礎(chǔ)框架為:
fig, ax = plt.subplots()ax.plot(df['x'],df['y'])
通過上面幾行代碼就可以畫出df表周一到周五y指標(biāo)的變化折線。

折線圖繪制示例
Matplotlib其實(shí)為作圖提供了兩套可視化接口,分別為:
?plt.plot()系列?fig, ax = plt.subplots(); ax.plot()?系列
根據(jù)官網(wǎng)教程,分別對應(yīng)MATLAB的陳述式語法和面向?qū)ο髮懛?,具體可參考tutorials:lifecycle.html[2]?,
個(gè)人理解,plt.plot()適合用于快速出圖,讀入一個(gè)數(shù)據(jù)表后想快速知道數(shù)據(jù)分布、指標(biāo)關(guān)系等,通過plt.plot()系列語句直接出圖,而ax.plot()更方便用來精細(xì)繪圖,接口對各種圖表元素的編輯很友好。
在Matplotlib官網(wǎng)搜索,通常能看到兩套接口,如搜繪制餅圖的關(guān)鍵詞pie,結(jié)果中的axes.Axes.pie對應(yīng)ax.pie()的用法,pyplot.pie對應(yīng)plt.pie()的函數(shù)接口。

兩套接口
ax.×××()的寫法看起來要寫的語句多些,但這種面向?qū)ο?object-oriented)的寫法通過fig, ax = plt.subplots()建立畫布(figure)和定義軸域(axes),能更明確在哪作畫和映射規(guī)則,給用戶更大的自由度和更精細(xì)的調(diào)參能力。Axes包含了一套坐標(biāo)軸(axis),確定了x/y坐標(biāo)軸之后,數(shù)值再確定對應(yīng)坐標(biāo),也就唯一確定了所在位置(這是二維情況下,更高維度就會(huì)對應(yīng)著更多的axis),散點(diǎn)圖是去確定點(diǎn)在軸域下的位置,柱狀圖是確定每個(gè)柱柱所在的位置,因此一套Axes就確定了唯一的獨(dú)立的圖,一個(gè)畫布可以有多套Axes。更具體的辨析可讀姚太多啊的一篇文章[3],簡單說就是ax.×××()更方便調(diào)細(xì)節(jié),初學(xué)者盡量避免用plt.×××系列來畫圖。
基礎(chǔ)圖表繪制
數(shù)據(jù)可視化從目的來說,是為了更直觀展示數(shù)據(jù)或數(shù)據(jù)之間的對比、分布或關(guān)聯(lián)關(guān)系。散點(diǎn)圖、折線圖、柱狀圖、條形圖、餅圖、直方圖是非常常用而基礎(chǔ)的可視化圖。個(gè)人認(rèn)為通過畫這幾種基礎(chǔ)圖并調(diào)細(xì)節(jié)是很好的學(xué)可視化實(shí)踐。

將數(shù)據(jù)映射為可視圖表
為了整體的美觀和一致性,本文都用了一套自定義配色,通過mpl.rcParams["axes.prop_cycle"] = mpl.cycler('color', ['1EAFAE', 'A3FFFF', '69FFFF'])?語句實(shí)現(xiàn)簡單改配色,具體關(guān)于mpl.rcParams后面再展開。
畫散點(diǎn)圖可以用兩種主要的方法,scatter(x,y)和plot(x,y,'o')?。通過ax.scatter(x,y)繪制以x為橫坐標(biāo),y為縱坐標(biāo)的散點(diǎn)圖,scatter的重要參數(shù)如下:
?x,y:對應(yīng)著x軸和y軸的數(shù)據(jù),散點(diǎn)畫在坐標(biāo)軸里的[xi,yi]處。?s,c,alpha: 對應(yīng)散點(diǎn)大小(size)、顏色(color)、透明度,都可以傳一個(gè)和點(diǎn)數(shù)量相同長度的數(shù)組,如s=df['z']可以做氣泡圖,一般氣泡圖為了防止遮蓋問題,通常設(shè)置一定的透明度,alpha的范圍為0到1。c='#BA5C25'設(shè)置點(diǎn)顏色,c賦值為一個(gè)數(shù)組可以做出每個(gè)點(diǎn)一個(gè)顏色的效果。?marker:設(shè)置點(diǎn)的形狀;?cmap:顏色映射;?norm:當(dāng)顏色c為一組浮點(diǎn)數(shù)時(shí),把值標(biāo)準(zhǔn)化到[0,1]做顏色映射,vmin和vamx參數(shù)是結(jié)合?norm?來用的;

散點(diǎn)圖參數(shù)示例
ax.plot(x,y,'o')也可以畫散點(diǎn)圖,ax.plot()核心是繪制坐標(biāo)系下的點(diǎn)和點(diǎn)之間的連線的,當(dāng)突出點(diǎn)的大小而省略線時(shí),就是散點(diǎn)圖了,同樣突出線就變成了折線圖。通過fmt(也就是format_string)參數(shù)來控制這些,包括點(diǎn)的形狀、顏色、線的風(fēng)格顏色等。折線圖基礎(chǔ)繪制效果可回看上一部分可視化基礎(chǔ)框架。
plot()的常用參數(shù)如下:
?x,y: x軸和y軸的數(shù)據(jù),當(dāng)plot()只有一個(gè)輸入列表或數(shù)組時(shí),參數(shù)被當(dāng)做y軸,也就是value,x軸以索引自動(dòng)生成,也就是ax.plot(y)相當(dāng)于ax.plot(range(len(y)),y);?fmt: 控制x,y繪制的折線的點(diǎn)形狀、顏色、線的風(fēng)格、顏色,fmt參數(shù)可分類為三種:顏色字符、風(fēng)格字符和標(biāo)記字符[4];?其他的lines.Line2D支持的屬性, 如color控制線顏色,marker控制點(diǎn)形狀,linestyle控制線風(fēng)格類型及linewidth控制線寬等,如果既設(shè)置了fmt又指定了color呢?可以實(shí)踐一下,線的顏色會(huì)根據(jù)color屬性最終顯示。

常用fmt字符意義整理
plot()除了plot(x,y,[fmt])這種寫法之外,還可以傳多套x,y以繪制多條折線,寫法是plot(x,y,[fmt],x2,y2,[fmt2],…)。
另外plot()還支持plot('col1','col2',data=df)這種寫法,這是對二維表格數(shù)據(jù)更友好的接口。本文講到的其他圖形如bar、barh等基本也都是支持ax.×××(df['x'],df['y']) 和ax.×××(x,y,data)寫法的。

plot() 3種寫法及結(jié)果圖
通過ax.bar(x,height)繪制柱狀圖,條形圖的繪制用ax.barh(y,width),因bar和barh的用法很類似,參數(shù)之間有對應(yīng)關(guān)系,這里結(jié)合著看。

柱狀圖繪制及參數(shù)理解
?x,height: x軸的值和各柱的高,相當(dāng)于折線圖的x,y;?width: 柱的寬度,默認(rèn)是0.8,也可以傳入一個(gè)數(shù)組,畫不等寬的柱狀圖;?bottom: 每個(gè)柱底部開始位置,默認(rèn)是0,改bottom可以畫堆積柱狀圖、瀑布圖等;?align: 柱狀的x是在柱底部中心還是邊緣,{'center', 'edge'},默認(rèn)是center;?data: 可以傳入一個(gè)DataFrame,用法和前面說到的ax.plot('col1','col2',data=df)一致;?其他像color(柱顏色)、edgecolor(柱邊框色)、linewidth(邊框線寬)等圖元屬性用法都一致,linewidth也是可以簡寫為lw的,顏色可以傳一個(gè)數(shù)組,可以畫出五彩斑斕的柱,也可借由這個(gè)參數(shù)美化瀑布圖;?條形圖barh的參數(shù)有barh(y,width,height,left,align),y是Y軸的值,每個(gè)柱的位置,因此barh的y對應(yīng)bar的x,barh的width對應(yīng)bar的height,barh的height對應(yīng)bar的width。每個(gè)柱開始的位置是left,對應(yīng)bar的bottom。align、data、color等一致。
注意的是柱狀圖繪制語句ax.bar(x,height)的返回值是一個(gè)容器(BarContainer),包含了所有畫出來的柱。通過這個(gè)返回值可以對柱進(jìn)行一些個(gè)性化的處理,另外的應(yīng)用就是根據(jù)返回柱的屬性給每個(gè)柱標(biāo)上文本標(biāo)簽。
#給柱狀圖標(biāo)上標(biāo)簽fig,ax= plt.subplots()rects=ax.bar(df['x'],df['y'])ax.set_ylim(0,100)for rect in rects:height = rect.get_height()ax.annotate('{}'.format(height),xy=(rect.get_x() + rect.get_width() / 2, height),xytext=(0,1), # y方向上偏移一個(gè)像素textcoords="offset points",ha='center', va='bottom')
通過給x以一定的偏移量,繪制簇狀柱形圖。代碼如下:
#簇狀柱 ClusterBarx = list(range(1,len(df)+1))width = 0.2 #每個(gè)柱的寬度x1=[i-width for i in x]x2=[i+width for i in x]fig, ax = plt.subplots(figsize=(6,5))rects1 = ax.bar(x1,df['y'], width*2, label='Men',color='#1EAFAE')rects2 = ax.bar(x2,df['z'], width*2, label='Women',color='#69FFFF')ax.set_xticks(x)ax.set_xticklabels(df['x'])ax.legend()

簇狀柱形圖
通過給bottom參數(shù)傳一個(gè)數(shù)組,可以畫堆疊柱狀圖:堆疊柱除了等值堆疊之外,還可以等比堆疊,思路就是將每個(gè)x對應(yīng)的柱都做一下數(shù)值變換,把柱的高度約束在[0,1],且堆疊之和為1,height=h[i]/sum(h)。
#堆疊柱狀圖fig,ax= plt.subplots()ax.bar(df['x'],df['y'],label='Men')ax.bar(df['x'],df['z'],bottom=df['y'],label='Women')ax.legend()#等比例堆疊柱fig,ax= plt.subplots()df['y1']=df.apply(lambda x:(x['y'])*100/(x['y']+x['z']),axis=1)df['z1']=df.apply(lambda x:(x['z'])*100/(x['y']+x['z']),axis=1)ax.bar(df['x'],df['y1'])ax.bar(df['x'],df['z1'],bottom=df['y1'])ax.set_ylim(0,100)#標(biāo)簽設(shè)置等代碼省略

堆疊柱狀圖繪制
調(diào)節(jié)width參數(shù)使得柱和柱之間的寬度為0,并對數(shù)據(jù)進(jìn)行統(tǒng)計(jì)在畫圖,可以用ax.bar()繪制直方圖,但也不需要這么復(fù)雜,Matplotlib提供了繪制直方圖的接口ax.hist(x,bins,normed),可以直接對某列數(shù)據(jù)繪制直方圖。x是需要統(tǒng)計(jì)分布的數(shù)據(jù)列,bins控制分箱的個(gè)數(shù),默認(rèn)是10。
箱線圖在數(shù)據(jù)分析中挺常用的,箱線圖對于數(shù)據(jù)分布有很好的展示作用,Matplotlib提供了boxplot(x)用于繪制箱線圖。
fig, ax= plt.subplots()ax.boxplot(df['y'])#箱線圖

用同一列數(shù)據(jù)繪制的直方圖與箱線圖
餅圖是可視化中基礎(chǔ)而重要的圖形,是各種數(shù)據(jù)報(bào)告的???,Matplotlib繪制餅圖時(shí)因?yàn)閤y軸默認(rèn)比例尺不同,為了得到不扁的餅,需設(shè)置xy軸1像素對應(yīng)的值相等。
#繪制餅圖fig,ax=plt.subplots(subplot_kw=dict(aspect="equal"))ax.pie(df['y']) #為了得到不扁的餅,設(shè)置xy軸比例尺相同#---#環(huán)狀圖fig, ax = plt.subplots(subplot_kw=dict(aspect="equal"))wps=dict(width=0.3, edgecolor='w')ax.pie(df['y'], radius=1,startangle=90,counterclock=False,wedgeprops=wps)ax.pie(df['z'], radius=1-0.3,startangle=90,counterclock=False,wedgeprops=wps)

餅圖與圓環(huán)圖
圖表元素調(diào)校
一張可視化圖上除了主要的點(diǎn)、線、面之外,文本標(biāo)簽、坐標(biāo)軸標(biāo)簽等也是很重要的可視媒介,特別是對于信息圖表而言。下面這張圖[5]基本囊括了用到的圖形元素:

Figure圖元的直觀展示
加文本可以通過?ax.text(x,y, "Text")?。添加標(biāo)題通常寫ax.set_title(),另外也可以用ax.title.set_text('title')或ax.set(title='ttl')設(shè)置標(biāo)題, 整理如下:

常用圖表標(biāo)簽添加語句
?ax.text(x,y, "Text"): 在坐標(biāo)[x,y]處添加文本Text,文本支持latex公式,如ax.text(2,6, r'$E=mc^2$', fontsize=15);?ax.set_title(): 添加標(biāo)題;?ax.set_ylim(0,4)?: 設(shè)置y軸值的范圍(類似于函數(shù)的值域),例如對于y=[],直接ax.plot(y)畫出來的折線圖y軸范圍是 ,通過ax.set_ylim(0,4)?可以顯示0~100范圍的效果。同理通過ax.set_ylim(0,4)設(shè)置x軸范圍(定義域);?ax.set_ylabel("Y axis label"): 給y軸加上坐標(biāo)軸標(biāo)題;?ax.tick_params(which='major', width=1.0): 細(xì)調(diào)坐標(biāo)軸刻度;?ax.legend()?: 設(shè)置圖例 ;
圖形元素設(shè)置除了文本類型之外,也可以往里加形狀 。
?加線:??import matplotlib.lines as lines;ax.add_artist(lines.Line2D([15,15], [0, 10],color='#1EAFAE')),其效果可參考矩陣圖繪制效果;?加帶箭頭的線:?ax.arrow(0, 0, 0.5, 0.5, head_width=0.05, head_length=0.1, fc='k', ec='k');?加一個(gè)垂直的平均線:?ax.axvline(x, ls='--', color='r'),那水平平均線呢?axhline(y=0, xmin=0, xmax=1, **kwargs);?加垂直或水平的強(qiáng)調(diào)矩形:?ax.axhspan(ymin, ymax, xmin=0, xmax=1, **kwargs)?和?ax.axvspan(xmin, xmax, ymin=0, ymax=1, **kwargs);?加矩形: patches.append(mpatches.Rectangle([0.5, 0.5], 0.5,0.8)),可用來畫甘特圖;?加圓形(及橢圓):?patches.append( mpatches.Ellipse((x,y), width, height));?加帶箭頭的形狀:?ax.annotate('箭頭文本', xy=(4,5), xytext=(3,2),color, arrowprops=dict( arrowstyle='->', connectionstyle="arc3")),加圖標(biāo)型的箭頭:patches.append( mpatches.Arrow(x,y, dx,dy,width));?加圖片:?mpimg.imread(ipath); ax.axis('off'); ax.imshow(img);
給散點(diǎn)圖加標(biāo)簽并加分隔線來繪制矩陣圖,以實(shí)踐一下以上方法:
import matplotlib.lines as linesfig, ax= plt.subplots()ax.plot(df['z'],df['y'],'o')ax.add_artist(lines.Line2D([70,70],[30,100],color='#000000',lw=3))#是[x1,x2],[y1,y2] 不是[x1,y1],[x2,y2]ax.add_artist(lines.Line2D([30,100],[65,65],color='#000000',lw=3))ax.set_xlim(30,100)ax.set_ylim(30,100)ax.set_xlabel("z")ax.set_ylabel("y")

矩陣圖繪制示例
繪制瀑布圖綜合運(yùn)用ax.bar()的參數(shù)和文本標(biāo)簽,并封裝為一個(gè)函數(shù),以后使用只需要調(diào)用就好:
#瀑布圖x=[17,-3,7,6] #原始數(shù)據(jù)def waterfall_chart(x):j=0 #sum(x) 最終柱的結(jié)果k=0 #k=x[i-1]x0=[]for i in x:if i<0:x0.append(j+i)else:x0.append(j)????????j+=i????x1=[abs(i)?for?i?in?x]c1=['#1EAFAE' if i>0 else '#69FFFF' for i in x]c1.append('#BA5C25')x0[0]=0x0.append(0)x1.append(j)x.append(j)w=list(range(1,len(x)+1))fig,ax= plt.subplots(figsize=(6,5))ax.bar(w,x0,alpha=0) #都透明度為0了,顏色不重要rects=ax.bar(w,x1,bottom=x0,color=c1) #顏色可傳一個(gè)數(shù)組的ax.set_ylim(0, 30)i=0for rect in rects: #加上適當(dāng)?shù)奈谋緲?biāo)簽height = rect.get_height()+x0[i]ax.annotate('{}'.format(x[i]),xy=(rect.get_x() + rect.get_width() / 2, height),????????????????xytext=(0,1),??textcoords="offset points",ha='center', va='bottom')i+=1ax.set_xticklabels(['','Q1','Q2','Q3','Q4','Ys'])return axwaterfall_chart(x)

瀑布圖繪制效果
組合圖
為了更好地展現(xiàn)數(shù)據(jù)間的聯(lián)系或變化,我們有時(shí)會(huì)需要將多種圖表類型用在同一張可視化圖里,一種是共用坐標(biāo)軸的組合圖,例如面積圖+柱狀圖的組合、散點(diǎn)+折線圖就是很基礎(chǔ)的組合圖。另一種是雙坐標(biāo)軸,很常見的圖是左邊的y軸是月活,畫柱狀圖,右邊的y軸是增長率,畫折線圖。

共用坐標(biāo)軸組合圖兩例子
棒棒糖圖(Lollipop)是將條形圖的柱變得很細(xì)并突出末端的一類圖,形似棒棒糖,特別適合于展示分類標(biāo)簽很多的數(shù)據(jù)。可以通過將柱狀圖和散點(diǎn)圖結(jié)合的方法繪制,Matplotlib庫繪制起來并不復(fù)雜,代碼如下。但對于一些散點(diǎn)圖的y軸不支持分類標(biāo)簽的庫來說,要畫棒棒糖圖還是挺復(fù)雜的。
y =[5,4,11,10,15,11,13,8,13,15,13,19]x=['c'+str(i)for i in range(len(y))]fig, ax= plt.subplots(figsize=(6,6))ax.barh(x,y,height=0.08,zorder=1)#圖層順序的解決方案ax.scatter(y,x,zorder=2,color='#ba5c25')
有時(shí)為了對比兩類數(shù)據(jù),除了用簇狀柱形圖或簇狀條形圖外,也可以試試啞鈴圖,理解了上面畫棒棒糖圖的方法之后,要組合出啞鈴圖并不難,對數(shù)據(jù)進(jìn)行一定運(yùn)算后用barh加兩個(gè)scatter就可以畫出來。

棒棒糖圖與啞鈴圖
帕累托圖是雙坐標(biāo)軸的可視化典例。帕累托圖特別適合展示符合長尾效應(yīng)的數(shù)據(jù)。Matplotlib給我們提供了ax.twinx()用于生成共用x軸的另一個(gè)Axes,效果就是左邊的y軸比例尺和右邊比例尺不一定一樣,能更好地將兩類圖進(jìn)行效果組合。
y=[23,162,51,119,12,3,8] #模擬數(shù)據(jù)x=[str(i) for i in range(2,len(y)+2)]y=sorted(y,reverse=True)ysum=sum(y)y2=[]cc=0for i in y:cc+=iy2.append(cc/ysum*100)fig = plt.figure()ax1 = fig.add_subplot(111)rects=ax1.bar(x,y,color='#1EAFAE')ax1.set_ylabel('Month IC')ax1.set_ylim(0, 180)ax2 = ax1.twinx()#https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.twinx.html#matplotlib.axes.Axes.twinxax2.set_ylim(0, 100)ax2.plot(x,?y2,'o',color='#FFA069',linewidth=2,ls='-')ax2.set_ylabel('%')for rect in rects:height = rect.get_height()ax1.annotate('{}'.format(height),xy=(rect.get_x() + rect.get_width() / 2, height),xytext=(0,1), # 1 points vertical offsettextcoords="offset points",ha='center', va='bottom')ax1.set_title("Pareto in Matplotlib") #

帕累托圖繪制效果
子圖
除了組合圖外,有時(shí)候我們也需要將多個(gè)圖并排以展現(xiàn)某種數(shù)據(jù)關(guān)系。前面說過一個(gè)畫布下可以有多套Axes,正常情況下我們只需要一套Axes用來畫圖,但是也經(jīng)常需要在一個(gè)畫布中畫多張圖,形成分面或子母圖的效果,前面我們基本都是寫fig, ax= plt.subplots(),實(shí)際上subplots()可以設(shè)置nrows、ncols參數(shù)生成多套Axes。
plt.subplots()的常用寫法有:
?plt.subplot(3,2,4):在全局繪圖區(qū)域中建立3行、2列的分區(qū)繪圖區(qū)域,并定位到第4個(gè)子圖區(qū)域,返回一個(gè)axes;?plt.subplot(324): 效果和上面subplot(3,2,4)的寫法一致;?plt.subplots(): 默認(rèn)1行1列,生成的axes就是一個(gè);?plt.subplots(3,2)?: 沒有指定繪圖編號,返回值包括一個(gè)figure和多個(gè)axes,和ax[0, 0].×××(x, y)搭配著用;?fig = plt.figure(); ax= fig.add_subplot(221):先建立一個(gè)畫布,在畫布上添加2x2個(gè)子圖,并定位到順序第一個(gè)子圖;

生成多個(gè)繪圖區(qū)域
圖中代碼在全局繪圖區(qū)域中建立n行、m列的分區(qū)繪圖區(qū)域,并定位到其中一個(gè)子圖區(qū)域。之后ax的用法和前面一致,不贅述。
生成的圖片在shell環(huán)境中彈出的界面有保存圖片的按鍵,在jupyter環(huán)境中可以點(diǎn)擊圖片然后右鍵保存。而如果要通過代碼保存圖片到本地,一般通過plt.savefig(fname,dpi=300)保存圖片,參數(shù)有文件保存路徑(fname)、圖片每英寸像素(dpi)、邊緣顏色(edgecolor)等。在shell環(huán)境中一般通過plt.show()展示圖片,而jupyter notebook中通常寫%matplotlib inline將圖片直接在Out[]里輸出展示。

inline vs show
Matplotlib的rcParams接口可以設(shè)置很多個(gè)性化內(nèi)容,包括剛提到的savefig的edgecolor默認(rèn)值,可以寫mpl.rcParams["savefig.edgecolor"]='blue'改變原來的默認(rèn)值white。直方圖的默認(rèn)分箱數(shù)可以通過rcParams["hist.bins"]=5改變。
而為了在Matplotlib中支持中文,各教程的解決方案基本都有mpl.rcParams['font.family']='SimHei'這句,就是將Matplotlib的字體替換為微軟雅黑。前面基礎(chǔ)圖表繪制部分通過更新mpl.rcParams["axes.prop_cycle"]改變了繪圖的主題色,Matplotlib本身是提供了備選的繪圖渲染的各種主題,可以通過style.use('ggplot')調(diào)用ggplot主題(想換回默認(rèn)主題用style.use('default'))。就像給輸入法換皮膚一樣,rcParams接口給了我們更多的自由度和個(gè)性化。
三維及科學(xué)可視化
三維可視化和科學(xué)可視化是Matplotlib特別擅長的領(lǐng)域,人類作為三維生物,對三維的圖像有一定的偏好,扁平化和三維各有優(yōu)勢,各有不同的應(yīng)用場合,能畫好二維可視化圖也該會(huì)畫三維的圖表,且一些場景用好三維有奇效。Matplotlib的三維可視化封裝在mpl_toolkits工具套件的mplot3d里,mplot3d下的API主要包括Axes3D(三維坐標(biāo)軸區(qū)域)、art3d.xx3D(三維圖元)和proj3d(三維坐標(biāo)變換)。
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 unused importfig = plt.figure()ax = fig.add_subplot(111, projection='3d')ax.bar(df['x'],df['y'], zs=0, zdir='y', alpha=0.8)ax.bar(df['x'],df['z'], zs=1, zdir='y', alpha=0.8)ax.bar(df['x'],df['y'], zs=2, zdir='y', alpha=0.8)ax.set_xlabel('X')ax.set_ylabel('Y')ax.set_zlabel('Z')ax.set_yticks([0,1,2])

繪制三維下的柱圖
三維可視化和科學(xué)可視化聯(lián)系很緊密,科研作圖中應(yīng)用廣泛,各種漂亮的參數(shù)曲面在官網(wǎng)示例里有很多,這里略過、當(dāng)然二維下也能畫出很優(yōu)美的函數(shù)圖像,結(jié)合numpy生成[0,2]之間的正弦函數(shù)曲線僅需4行代碼:
t = np.arange(0.0, 2.0, 0.01)s = 1 + np.sin(2 * np.pi * t)fig, ax = plt.subplots()ax.plot(t,?s)

科學(xué)可視化之正弦函數(shù)圖像
繪制指數(shù)函數(shù)、分形的雪花曲線也是類似的過程,在官網(wǎng)案例集有類似的例子,具體這里不展開。
總結(jié)下本文從Matplotlib的可視化基礎(chǔ)框架一步步畫散點(diǎn)、折線、柱狀、箱線等圖,通過理解參數(shù)拓展畫了瀑布圖、矩陣圖、棒棒糖圖等,并且微調(diào)坐標(biāo)軸文本、標(biāo)題等圖形元素,讓可視化更完備,通過雙y軸繪制帕累托圖等組合圖,也繪制了包含多張子圖的圖和三維圖。
通過以上實(shí)踐可以看到的Matplotlib可視化語法的特點(diǎn)是繪圖對象和標(biāo)簽標(biāo)題等元素有一定獨(dú)立性,且有不同層級的接口可以用來微調(diào)元素,例如設(shè)置標(biāo)題就有多種寫法 ,Matplotlib不同于ggplot2的管道寫法、也不同于Altair等庫將數(shù)據(jù)傳到chart對象再調(diào)用mark_bar()等確定繪制什么圖??梢暬且每?,也不能忘了所展現(xiàn)的數(shù)據(jù)與數(shù)據(jù)間的關(guān)系是重點(diǎn)。

本文思維導(dǎo)圖
最后在極坐標(biāo)下繪制一個(gè)心形線結(jié)束本文。
點(diǎn)擊 閱讀原文?可直達(dá)文中繪圖代碼的jupyter notebook文檔。有任何建議歡迎留言交流。
#極坐標(biāo)繪心形線import numpy as nptheta= np.arange(0, 2*np.pi, 0.05)r=5*(1-np.sin(theta)) #a取5ax = plt.subplot(111, projection='polar')ax.plot(theta, r,lw=3)ax.grid(True)ax.text(1.56,6,'r=a(1-sinθ)',ha='center',fontsize=18,color='#1EAFAE')

“極坐標(biāo)繪心形線”
References
[1]?官網(wǎng),豐富而全面的參考:?https://matplotlib.org/[2]?兩種寫法及繪圖生命周期:?
https://matplotlib.org/tutorials/introductory/lifecycle.html#sphx-glr-tutorials-introductory-lifecycle-py[3]?matplotlib:先搞明白plt. /ax./ fig再畫:?
https://zhuanlan.zhihu.com/p/93423829[4]?嵩天老師MOOC課程:?
https://www.icourse163.org/course/0809BIT021B-1001870002[5]?Figure上的圖元:?
https://matplotlib.org/tutorials/introductory/usage.html
數(shù)據(jù)森麟公眾號的交流群已經(jīng)建立,許多小伙伴已經(jīng)加入其中,感謝大家的支持。大家可以在群里交流關(guān)于數(shù)據(jù)分析&數(shù)據(jù)挖掘的相關(guān)內(nèi)容,還沒有加入的小伙伴可以掃描下方管理員二維碼,進(jìn)群前一定要關(guān)注公眾號奧,關(guān)注后讓管理員幫忙拉進(jìn)群,期待大家的加入。
管理員二維碼:
