Python 數據可視化利器

尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️

加入LINE好友

(給Python開發者加星標,提升Python技能)

作者:zone7(本文來自作者投稿,簡介見末尾)

Python 數據可視化利器 科技 第1張

概述

  • 前言

  • 推薦

  • plotly

  • bokeh

  • pyecharts

  • 後記

前言

前段時間有讀者向我反映,想看看數據可視化方面的文章,這不?現在就開始寫了,如果你想看哪些方面的文章,可以通過留言或者後台告訴我。數據可視化的第三方庫挺多的,這里我主要推薦兩個,分別是 bokeh、pyecharts。如果我的文章對你有幫助,歡迎關注、點讚、轉PO,這樣我會更有動力做原創分享。

推薦

數據可視化的庫有挺多的,這里推薦幾個比較常用的:

  • Matplotlib

  • Plotly

  • Seaborn

  • Ggplot

  • Bokeh

  • Pyechart

  • Pygal

Plotly

plotly 文檔地址(https://plot.ly/python/#financial-charts)

使用方式:

plotly 有 online 和 offline 兩種方式,這里只介紹 offline 的。

這是 plotly 官方教程的一部分

importplotly.plotlyaspyimportnumpyasnpdata=[dict(visible=False,line=dict(color='#00CED1',width=6),#配置線寬和顏色name='?='+str(step),x=np.arange(0,10,0.01),#x軸參數y=np.sin(step*np.arange(0,10,0.01)))forstepinnp.arange(0,5,0.1)]#y軸參數data[10]['visible']=Truepy.iplot(data,filename='SingleSineWave')

只要將最後一行中的

py.iplot

替換為下面代碼

py.offline.plot

便可以運行。

漏鬥圖

這個圖代碼太長了,就不 po 出來了。

Basic Box Plot

好吧,不知道怎麼翻譯,直接用原名。

importplotly.plotlyimportplotly.graph_objsasgoimportnumpyasnpy0=np.random.randn(50)-1y1=np.random.randn(50)+1trace0=go.Box(y=y0)trace1=go.Box(y=y1)data=[trace0,trace1]plotly.offline.plot(data)

Wind Rose Chart

好吧,不知道怎麼翻譯,直接用原名。

importplotly.graph_objsasgotrace1=go.Barpolar(r=[77.5,72.5,70.0,45.0,22.5,42.5,40.0,62.5],text=['North','N-E','East','S-E','South','S-W','West','N-W'],name='11-14m/s',marker=dict(color='rgb(106,81,163)'))trace2=go.Barpolar(r=[57.49999999999999,50.0,45.0,35.0,20.0,22.5,37.5,55.00000000000001],text=['North','N-E','East','S-E','South','S-W','West','N-W'],#滑鼠浮動標籤文字描述name='8-11m/s',marker=dict(color='rgb(158,154,200)'))trace3=go.Barpolar(r=[40.0,30.0,30.0,35.0,7.5,7.5,32.5,40.0],text=['North','N-E','East','S-E','South','S-W','West','N-W'],name='5-8m/s',marker=dict(color='rgb(203,201,226)'))trace4=go.Barpolar(r=[20.0,7.5,15.0,22.5,2.5,2.5,12.5,22.5],text=['North','N-E','East','S-E','South','S-W','West','N-W'],name='<5m/s',marker=dict(color='rgb(242,240,247)'))data=[trace1,trace2,trace3,trace4]layout=go.Layout(title='WindSpeedDistributioninLaurel,NE',font=dict(size=16),legend=dict(font=dict(size=16)),radialaxis=dict(ticksuffix='%'),orientation=270)fig=go.Figure(data=data,layout=layout)plotly.offline.plot(fig,filename='polar-area-chart')

Basic Ternary Plot with Markers

篇幅有點長,這里就不 po 代碼了。

Bokeh

這里展示一下常用的圖表和比較搶眼的圖表,詳細的文檔可查看(https://bokeh.pydata.org/en/latest/docs/user_guide/categorical.html)

條形圖

這配色看著還挺舒服的,比 pyecharts 條形圖的配色好看一點。

條形圖
frombokeh.ioimportshow,output_filefrombokeh.modelsimportColumnDataSourcefrombokeh.palettesimportSpectral6frombokeh.plottingimportfigureoutput_file("colormapped_bars.html")#配置輸出文件名fruits=['Apples','魅族','OPPO','VIVO','小米','華為']#數據counts=[5,3,4,2,4,6]#數據source=ColumnDataSource(data=dict(fruits=fruits,counts=counts,color=Spectral6))p=figure(x_range=fruits,y_range=(0,9),plot_height=250,title="FruitCounts",toolbar_location=None,tools="")#條形圖配置項p.vbar(x='fruits',top='counts',width=0.9,color='color',legend="fruits",source=source)p.xgrid.grid_line_color=None#配置網格線顏色p.legend.orientation="horizontal"#圖表方向為水平方向p.legend.location="top_center"show(p)#展示圖表

年度條形圖

可以對比不同時間點的量。

年度條形圖
frombokeh.ioimportshow,output_filefrombokeh.modelsimportColumnDataSource,FactorRangefrombokeh.plottingimportfigureoutput_file("bars.html")#輸出文件名fruits=['Apple','魅族','OPPO','VIVO','小米','華為']#參數years=['2015','2016','2017']#參數data={'fruits':fruits,'2015':[2,1,4,3,2,4],'2016':[5,3,3,2,4,6],'2017':[3,2,4,4,5,3]}x=[(fruit,year)forfruitinfruitsforyearinyears]counts=sum(zip(data['2015'],data['2016'],data['2017']),())source=ColumnDataSource(data=dict(x=x,counts=counts))p=figure(x_range=FactorRange(*x),plot_height=250,title="FruitCountsbyYear",toolbar_location=None,tools="")p.vbar(x='x',top='counts',width=0.9,source=source)p.y_range.start=0p.x_range.range_padding=0.1p.xaxis.major_label_orientation=1p.xgrid.grid_line_color=Noneshow(p)

餅圖

餅圖
fromcollectionsimportCounterfrommathimportpiimportpandasaspdfrombokeh.ioimportoutput_file,showfrombokeh.palettesimportCategory20cfrombokeh.plottingimportfigurefrombokeh.transformimportcumsumoutput_file("pie.html")x=Counter({'中國':157,'美國':93,'日本':89,'巴西':63,'德國':44,'印度':42,'義大利':40,'澳大利亞':35,'法國':31,'西班牙':29})data=pd.DataFrame.from_dict(dict(x),orient='index').reset_index().rename(index=str,columns={0:'value','index':'country'})data['angle']=data['value']/sum(x.values())*2*pidata['color']=Category20c[len(x)]p=figure(plot_height=350,title="PieChart",toolbar_location=None,tools="hover",tooltips="@country:@value")p.wedge(x=0,y=1,radius=0.4,start_angle=cumsum('angle',include_zero=True),end_angle=cumsum('angle'),line_color="white",fill_color='color',legend='country',source=data)p.axis.axis_label=Nonep.axis.visible=Falsep.grid.grid_line_color=Noneshow(p)

條形圖

年度水果進出口
frombokeh.ioimportoutput_file,showfrombokeh.modelsimportColumnDataSourcefrombokeh.palettesimportGnBu3,OrRd3frombokeh.plottingimportfigureoutput_file("stacked_split.html")fruits=['Apples','Pears','Nectarines','Plums','Grapes','Strawberries']years=["2015","2016","2017"]exports={'fruits':fruits,'2015':[2,1,4,3,2,4],'2016':[5,3,4,2,4,6],'2017':[3,2,4,4,5,3]}imports={'fruits':fruits,'2015':[-1,0,-1,-3,-2,-1],'2016':[-2,-1,-3,-1,-2,-2],'2017':[-1,-2,-1,0,-2,-2]}p=figure(y_range=fruits,plot_height=250,x_range=(-16,16),title="Fruitimport/export,byyear",toolbar_location=None)p.hbar_stack(years,y='fruits',height=0.9,color=GnBu3,source=ColumnDataSource(exports),legend=["%sexports"%xforxinyears])p.hbar_stack(years,y='fruits',height=0.9,color=OrRd3,source=ColumnDataSource(imports),legend=["%simports"%xforxinyears])p.y_range.range_padding=0.1p.ygrid.grid_line_color=Nonep.legend.location="top_left"p.axis.minor_tick_line_color=Nonep.outline_line_color=Noneshow(p)

散點圖

散點圖
frombokeh.plottingimportfigure,output_file,showoutput_file("line.html")p=figure(plot_width=400,plot_height=400)p.circle([1,2,3,4,5],[6,7,2,4,5],size=20,color="navy",alpha=0.5)show(p)

六邊形圖

這兩天,馬蜂窩剛被發現數據造假,這不,與馬蜂窩應應景。

六邊形圖
importnumpyasnpfrombokeh.ioimportoutput_file,showfrombokeh.plottingimportfigurefrombokeh.util.heximportaxial_to_cartesianoutput_file("hex_coords.html")q=np.array([0,0,0,-1,-1,1,1])r=np.array([0,-1,1,0,1,-1,0])p=figure(plot_width=400,plot_height=400,toolbar_location=None)#p.grid.visible=False#配置網格是否可見p.hex_tile(q,r,size=1,fill_color=["firebrick"]*3+["navy"]*4,line_color="white",alpha=0.5)x,y=axial_to_cartesian(q,r,1,"pointytop")p.text(x,y,text=["(%d,%d)"%(q,r)for(q,r)inzip(q,r)],text_baseline="middle",text_align="center")show(p)

環比條形圖

這個做到挺厲害的,看了一眼就吸引了我。我在代碼中都做了一些註釋,希望對你理解有幫助。註:圓心為正中央,即直角坐標系中標籤為(0,0)的地方。

環比條形圖
fromcollectionsimportOrderedDictfrommathimportlog,sqrtimportnumpyasnpimportpandasaspdfromsix.movesimportcStringIOasStringIOfrombokeh.plottingimportfigure,show,output_fileantibiotics="""bacteria,penicillin,streptomycin,neomycin,gram結核分枝桿菌,800,5,2,negative沙門氏菌,10,0.8,0.09,negative變形桿菌,3,0.1,0.1,negative肺炎克雷伯氏菌,850,1.2,1,negative布魯氏菌,1,2,0.02,negative銅綠假單胞菌,850,2,0.4,negative大腸桿菌,100,0.4,0.1,negative產氣桿菌,870,1,1.6,negative白色葡萄球菌,0.007,0.1,0.001,positive溶血性鏈球菌,0.001,14,10,positive草綠色鏈球菌,0.005,10,40,positive肺炎雙球菌,0.005,11,10,positive"""drug_color=OrderedDict([#配置中間標籤名稱與顏色("盤尼西林","#0d3362"),("鏈黴素","#c64737"),("新黴素","black"),])gram_color={"positive":"#aeaeb8","negative":"#e69584",}#讀取數據df=pd.read_csv(StringIO(antibiotics),skiprows=1,skipinitialspace=True,engine='python')width=800height=800inner_radius=90outer_radius=300-10minr=sqrt(log(.001*1E4))maxr=sqrt(log(1000*1E4))a=(outer_radius-inner_radius)/(minr-maxr)b=inner_radius-a*maxrdefrad(mic):returna*np.sqrt(np.log(mic*1E4))+bbig_angle=2.0*np.pi/(len(df)+1)small_angle=big_angle/7#整體配置p=figure(plot_width=width,plot_height=height,title="",x_axis_type=None,y_axis_type=None,x_range=(-420,420),y_range=(-420,420),min_border=0,outline_line_color="black",background_fill_color="#f0e1d2")p.xgrid.grid_line_color=Nonep.ygrid.grid_line_color=None#annularwedgesangles=np.pi/2-big_angle/2-df.index.to_series()*big_angle#計算角度colors=[gram_color[gram]forgramindf.gram]#配置顏色p.annular_wedge(0,0,inner_radius,outer_radius,-big_angle+angles,angles,color=colors,)#smallwedgesp.annular_wedge(0,0,inner_radius,rad(df.penicillin),-big_angle+angles+5*small_angle,-big_angle+angles+6*small_angle,color=drug_color['盤尼西林'])p.annular_wedge(0,0,inner_radius,rad(df.streptomycin),-big_angle+angles+3*small_angle,-big_angle+angles+4*small_angle,color=drug_color['鏈黴素'])p.annular_wedge(0,0,inner_radius,rad(df.neomycin),-big_angle+angles+1*small_angle,-big_angle+angles+2*small_angle,color=drug_color['新黴素'])#繪制大圓和標籤labels=np.power(10.0,np.arange(-3,4))radii=a*np.sqrt(np.log(labels*1E4))+bp.circle(0,0,radius=radii,fill_color=None,line_color="white")p.text(0,radii[:-1],[str(r)forrinlabels[:-1]],text_font_size="8pt",text_align="center",text_baseline="middle")#半徑p.annular_wedge(0,0,inner_radius-10,outer_radius+10,-big_angle+angles,-big_angle+angles,color="black")#細菌標籤xr=radii[0]*np.cos(np.array(-big_angle/2+angles))yr=radii[0]*np.sin(np.array(-big_angle/2+angles))label_angle=np.array(-big_angle/2+angles)label_angle[label_angle<-np.pi/2]+=np.pi#easiertoreadlabelsontheleftside#繪制各個細菌的名字p.text(xr,yr,df.bacteria,angle=label_angle,text_font_size="9pt",text_align="center",text_baseline="middle")#繪制圓形,其中數字分別為x軸與y軸標籤p.circle([-40,-40],[-370,-390],color=list(gram_color.values()),radius=5)#繪制文字p.text([-30,-30],[-370,-390],text=["Gram-"+grforgringram_color.keys()],text_font_size="7pt",text_align="left",text_baseline="middle")#繪制矩形,中間標籤部分。其中-40,-40,-40為三個矩形的x軸坐標。18,0,-18為三個矩形的y軸坐標p.rect([-40,-40,-40],[18,0,-18],width=30,height=13,color=list(drug_color.values()))#配置中間標籤文字、文字大小、文字對齊方式p.text([-15,-15,-15],[18,0,-18],text=list(drug_color),text_font_size="9pt",text_align="left",text_baseline="middle")output_file("burtin.html",title="burtin.pyexample")show(p)

元素周期表

元素周期表,這個做到好牛逼啊,距離初三剛開始學化學已經很遙遠了,想當年我還是化學課代表呢!由於基本用不到化學了,這里就不做到了。

元素周期表

真實狀態

Pyecharts

pyecharts 也是一個比較常用的數據可視化庫,用得也是比較多的了,是百度 echarts 庫的 python 支持。這里也展示一下常用的圖表。文檔地址為(http://pyecharts.org/#/zh-cn/prepare?id=%E5%AE%89%E8%A3%85-pyecharts)

條形圖

條形圖
frompyechartsimportBarbar=Bar("我的第一個圖表","這里是副標題")bar.add("服裝",["襯衫","羊毛衫","雪紡衫","褲子","高跟鞋","襪子"],[5,20,36,10,75,90])#bar.print_echarts_options()#該行只為了列印配置項,方便調試時使用bar.render()#生成本地HTML文件

散點圖

散點圖
frompyechartsimportPolarimportrandomdata_1=[(10,random.randint(1,100))foriinrange(300)]data_2=[(11,random.randint(1,100))foriinrange(300)]polar=Polar("極坐標系-散點圖示例",width=1200,height=600)polar.add("",data_1,type='scatter')polar.add("",data_2,type='scatter')polar.render()

餅圖

餅圖
importrandomfrompyechartsimportPieattr=['A','B','C','D','E','F']pie=Pie("餅圖示例",width=1000,height=600)pie.add("",attr,[random.randint(0,100)for_inrange(6)],radius=[50,55],center=[25,50],is_random=True,)pie.add("",attr,[random.randint(20,100)for_inrange(6)],radius=[0,45],center=[25,50],rosetype="area",)pie.add("",attr,[random.randint(0,100)for_inrange(6)],radius=[50,55],center=[65,50],is_random=True,)pie.add("",attr,[random.randint(20,100)for_inrange(6)],radius=[0,45],center=[65,50],rosetype="radius",)pie.render()

詞雲

這個是我在前面的文章中用到的圖片實例,這里就不 po 具體數據了。

詞雲
frompyechartsimportWordCloudname=['SamSClub']#詞條value=[10000]#權重wordcloud=WordCloud(width=1300,height=620)wordcloud.add("",name,value,word_size_range=[20,100])wordcloud.render()

樹圖

這個是我在前面的文章中用到的圖片實例,這里就不 po 具體數據了。

樹圖
frompyechartsimportTreeMapdata=[#鍵值對數據結構{value:1212,#數值#子節點children:[{#子節點數值value:2323,#子節點名name:'descriptionofthisnode',children:[...],},{value:4545,name:'descriptionofthisnode',children:[{value:5656,name:'descriptionofthisnode',children:[...]},...]}]},...]treemap=TreeMap(title,width=1200,height=600)#設置標題與寬高treemap.add("深圳",data,is_label_show=True,label_pos='inside',label_text_size=19)treemap.render()

地圖

地圖
frompyechartsimportMapvalue=[155,10,66,78,33,80,190,53,49.6]attr=["福建","山東","北京","上海","甘肅","新疆","河南","廣西","西藏"]map=Map("Map結合VisualMap示例",width=1200,height=600)map.add("",attr,value,maptype="china",is_visualmap=True,visual_text_color="#000",)map.render()

3D 散點圖

frompyechartsimportScatter3Dimportrandomdata=[[random.randint(0,100),random.randint(0,100),random.randint(0,100)]for_inrange(80)]range_color=['#313695','#4575b4','#74add1','#abd9e9','#e0f3f8','#ffffbf','#fee090','#fdae61','#f46d43','#d73027','#a50026']scatter3D=Scatter3D("3D散點圖示例",width=1200,height=600)#配置寬高scatter3D.add("",data,is_visualmap=True,visual_range_color=range_color)#設置顏色等scatter3D.render()#渲染

後記

大概介紹就是這樣了,三個庫的功能都挺強大的,bokeh 的中文資料會少一點,如果閱讀英文有點難度,還是建議使用 pyecharts 就好。總體也不是很難,按照文檔來修改數據都能夠直接上手使用。主要是多練習。

【本文作者】

Zone:一只愛折騰的後端攻城獅,喜歡寫文分享。個人公眾號:zone7

推薦閱讀

(點擊標題可跳轉閱讀)

教你用 Python 做一個物體檢測系統

改善 Python 程序的 91 個建議

讓 Python 代碼更易維護的七種武器

覺得本文對你有幫助?請分享給更多人

關注「Python開發者」加星標,提升Python技能

Python 數據可視化利器 科技 第23張

About 尋夢園
尋夢園是台灣最大的聊天室及交友社群網站。 致力於發展能夠讓會員們彼此互動、盡情分享自我的平台。 擁有數百間不同的聊天室 ,讓您隨時隨地都能找到志同道合的好友!