大家可以关注知乎或微信公众号的share16,我们也会同步更新此文章。
关于Plotly的内容 1
对数据的分析离不开数据的可视化,相对于Python在数据分析、人工智能、量化投资等领域中的发展,在数据可视化方面的发展有些滞后。最经典的Python可视化绘图库莫过于 Matplotlib了;为了绘出更漂亮的图像,Python开源社区开发出了Seaborn绘图模块,它本质上是对 Matplotlib的封装,绘图效果更符合现代人的审美观。
为了解决 Python在可视化中存在的问题, Plotly 应运而生,它是一个基于JavaScript的动态绘图模块。Plotly的绘图效果与我们在网页上看到的动态交互式绘图效果是一样的,其默认的绘图结果是一个HTML网页文件,通过浏览器就可以查看。我们可以把这个HTML文件分享给其他人,对方看到的效果与我们在本机上看到的效果完全一样。Plotly在绘图模块上是Matplotlib强有力的竞争对手,Plotly绘图的种类丰富、效果美观、易于保存与分享,因而越来越受数据分析人士的喜爱。
Plotly绘图底层使用的是plotly.js,plotly.js基于D3.js、stack.gl和SVG,用JavaScript在网页上实现类似MATLAB和Matplotlib的图形展示功能,支持数十种图形,包括2D和3D图形,交互流畅,可以满足一般科学计算的需要。目前已经有Python、MATLAB、R语言、Jupyter等多种版本的API接口。
Plotly绘图模块库可直接生成PNG等图像文件,与Bokeh绘图模块库和各种基于Web的JavaScript图表模块库类似,生成的是一个内置JavaScript脚本的HTML网页文件,虽然文件比Bokeh绘图模块库生成的文件略大,但在互动性方面,Plotly绘图模块库强大得多。
Plotly的内置信息
Plotly的基本绘图流程
Plotly的离线绘图功能 允许在没有网络的情况下绘图,并把图像保存到本地。
import pandas as pd
import plotly.graph_objs as go
import plotly.express as px
from plotly.subplots import make_subplots #子图
from plotly.offline import init_notebook_mode,iplot,plot #初始化、绘图
init_notebook_mode(connected=False)
df = pd.DataFrame({'x':[1,2,3,4,5],'y1':[22,30,27,32,30],'y2':[26,31,32,33,32]})
trace1 = go.Scatter(x=df.x,y=df.y1,mode='markers',name='y1',marker={'symbol':'square'})
trace2 = go.Scatter(x=df.x,y=df.y2,mode='markers',name='y2',marker={'symbol':'circle'})
trace = [trace1,trace2]
layout = {'title':{'text':'散点图','x':0.5,'font':{'color':'red','size':26}},
'showlegend':False}
fig = make_subplots(rows=1,cols=3,subplot_titles=['express','graph_objects','add_scatter'])
fig.add_trace(px.scatter(data_frame=df,x='x',y='y1',symbol_sequence=['square']).data[0],row=1,col=1)
fig.add_trace(px.scatter(data_frame=df,x='x',y='y2',symbol_sequence=['circle']).data[0],row=1,col=1)
fig.add_trace(trace1,row=1,col=2)
fig.add_trace(trace2,row=1,col=2)
fig.add_scatter(x=df.x,y=df.y1,mode='markers',name='y1',row=1,col=3)
fig.add_scatter(x=df.x,y=df.y2,mode='markers',name='y2',row=1,col=3)
fig.update_layout(layout)
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
init_notebook_mode(connected=False)
df = pd.DataFrame({'x':[1,2,3,4,5],'y1':[22,30,27,32,30],'y2':[26,31,32,33,32]})
trace1 = go.Scatter(x=df.x,y=df.y1,mode='lines+markers',name='y1',
marker={'symbol':'square'},line={'dash':'solid','shape':'linear'})
trace2 = go.Scatter(x=df.x,y=df.y2,mode='lines+markers',name='y2',
marker={'symbol':'circle'},line={'dash':'dashdot','shape':'spline'})
trace = [trace1,trace2]
layout = {'title':{'text':'线形图','x':0.5,'font':{'color':'red','size':26}},
'showlegend':False}
fig = make_subplots(rows=1,cols=3,subplot_titles=['express','graph_objects','add_scatter'])
fig.add_trace(px.line(data_frame=df,x='x',y='y1',line_dash_sequence=['solid'],line_shape='linear',\
markers=True,symbol_sequence=['square']).data[0],row=1,col=1)
fig.add_trace(px.line(data_frame=df,x='x',y='y2',line_dash_sequence=['dot'],line_shape='spline',\
markers=True,symbol_sequence=['circle']).data[0],row=1,col=1)
fig.add_trace(trace1,row=1,col=2)
fig.add_trace(trace2,row=1,col=2)
fig.add_scatter(x=df.x,y=df.y1,mode='lines+markers',name='y1',row=1,col=3)
fig.add_scatter(x=df.x,y=df.y2,mode='lines+markers',name='y2',row=1,col=3)
fig.update_layout(layout)
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
条形图 是由柱状图修改参数(即orientation=‘h’)而来的。
init_notebook_mode(connected=False)
df = pd.DataFrame({'x':[1,2,3,4,5],'y1':[22,30,27,32,30],'y2':[26,31,32,33,32]})
trace1 = go.Bar(x=df.x,y=df.y1,name='y1')
trace2 = go.Bar(x=df.x,y=df.y2,name='y2')
trace = [trace1,trace2]
layout = {'title':{'text':'柱状图','x':0.5,'font':{'color':'red','size':26}},
'showlegend':False,
'barmode':'stack'}
fig = make_subplots(rows=1,cols=3,subplot_titles=['express','graph_objects','add_bar'])
fig.add_trace(px.bar(data_frame=df,x='x',y='y1',color_discrete_sequence=['orange']).data[0],row=1,col=1)
fig.add_trace(px.bar(data_frame=df,x='x',y='y2',color_discrete_sequence=['lightskyblue']).data[0],row=1,col=1)
fig.add_trace(trace1,row=1,col=2)
fig.add_trace(trace2,row=1,col=2)
fig.add_bar(x=df.x,y=df.y1,name='y1',row=1,col=3)
fig.add_bar(x=df.x,y=df.y2,name='y2',row=1,col=3)
fig.update_layout(layout)
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
Pie函数中最常用的两个属性一个是values,用于赋给其需要可视化的数据;另一个是labels,表示不同数据对应的标签;绘制环形饼图,只需在Pie函数中设置控制环形中心空白大小的hole属性即可实现。
在子图中,绘制饼图时,要对子图进行设置(即参数specs),子图默认的type是xy,要修正为pie,代码如下。
init_notebook_mode(connected=False)
df = pd.DataFrame({'x':[1,2,3,4,5],'y1':[22,30,27,32,30],'y2':[26,31,32,33,32]})
trace1 = go.Pie(labels=df.x,values=df.y1)
trace = [trace1]
layout = {'title':{'text':'饼图','x':0.5,'font':{'color':'red','size':26}},
'showlegend':False}
fig = make_subplots(rows=1,cols=3,subplot_titles=['express','graph_objects','add_pie'],
specs=[[{'type':'pie'},{'type':'pie'},{'type':'pie'}]])
fig.add_trace(px.pie(data_frame=df,labels='x',values='y1').data[0],row=1,col=1)
fig.add_trace(trace1,row=1,col=2)
fig.add_pie(labels=df.x,values=df.y1,textinfo='label+percent',row=1,col=3)
fig.update_traces(textinfo='label+percent',textposition='inside')
fig.update_layout(layout)
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
构建热力图的方法有:go.Heatmap、px.imshow、px.density_heatmap、plotly.figure_factory.create_annotated_heatmap。
init_notebook_mode(connected=False)
df = pd.DataFrame({'x':[1,2,3,4,5],'y1':[22,30,27,32,30],'y2':[26,31,32,33,32]})
df1 = df.corr()
trace1 = go.Heatmap(x=df1.index,y=df1.columns,z=df1,texttemplate='%{z:.2f}',
colorscale='greens',showscale=False)
layout = {'title':{'text':'热力图','x':0.5,'font':{'color':'red','size':26}}}
fig = make_subplots(rows=1,cols=3,subplot_titles=['express','graph_objects','add_heatmap'])
fig.add_trace(px.imshow(df1,text_auto='.2f').data[0],row=1,col=1)
fig.update_layout(colorscale={'sequential':'sunset'},coloraxis={'showscale':False})
fig.add_trace(trace1,row=1,col=2)
fig.add_heatmap(x=df1.index,y=df1.columns,z=df1,texttemplate='%{z:.2f}',
colorscale='rainbow',showscale=False,row=1,col=3)
fig.update_layout(layout)
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
init_notebook_mode(connected=False)
df = pd.DataFrame({'x':[1,2,3,4,5],'y1':[22,30,27,32,30],'y2':[26,31,32,33,32]})
df1 = df.corr().stack().reset_index()
df1.columns = ['left','right','value']
layout = {'title':{'text':'热力图:px.density_heatmap','x':0.5,'font':{'color':'red','size':26}},
'colorscale':{'sequential':'sunset'},
# density_heatmap函数 可设置参数color_continuous_scale
'coloraxis':{'showscale':False}}
px.density_heatmap(data_frame=df1,x='left',y='right',z='value',text_auto='.2f',
template={'layout':layout})
构建点地图的方法有:go.Scattergeo、px.scatter_geo;此外,地图函数还有go.Scattermapbox、go.Choropleth、px.scatter_mapbox、px.choropleth等等。
init_notebook_mode(connected=False)
df = pd.read_csv('XXX/directory.csv',encoding='gbk')
trace = go.Scattergeo(lat=df.Latitude,lon=df.Longitude,text=df[['Store Name','Ownership Type']])
layout = {'title':{'text':'点地图','x':0.5,'font':{'color':'red','size':26}},
#根据fig.data中geo键对应的值,设置projection(rotation旋转)
'geo2':{'projection':{'rotation':{'lat':30,'lon':110}}},
'geo3':{'projection':{'type':'orthographic',
'rotation':{'lat':30,'lon':110}}},
'showlegend':False}
fig = make_subplots(rows=1,cols=3,subplot_titles=['express','graph_objects','add_scattergeo'],
specs=[[{'type':'scattergeo'},{'type':'scattergeo'},{'type':'scattergeo'}]])
fig.add_trace(px.scatter_geo(data_frame=df,lat='Latitude',lon='Longitude',
hover_name='City',hover_data=['Store Name','Ownership Type']).data[0],
row=1,col=1)
fig.add_trace(trace,row=1,col=2)
fig.add_scattergeo(lat=df.Latitude,lon=df.Longitude,row=1,col=3)
fig.update_layout(layout)
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
在Plotly中,animation_frame和animation_group用于控制动画的效果。这两个参数通常一起使用,可以创建更加丰富的动画效果。例如,在时间序列数据的折线图中,可以使用animation_frame参数来控制每一帧所显示的时间点,而使用animation_group参数来控制不同数据序列的动画效果。
此外,px.scatter、px.line、px.bar等函数中有这两个参数。
init_notebook_mode(connected=False)
df = px.data.gapminder()
layout = {'title':{'text':'时间线轮播图','x':0.5,'font':{'color':'red','size':26}}}
fig = px.scatter(data_frame=df,x='gdpPercap',y='lifeExp',size='pop',size_max=55,
color='continent',hover_name='country',log_x=True,range_x=[100,100000],
range_y=[25,90],animation_frame='year',animation_group='country')
fig.update_layout(layout)
fig['layout'].pop('updatemenus') #删除 animation buttons
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
init_notebook_mode(connected=False)
df = pd.read_csv('XXX/s.csv',encoding='gbk',parse_dates=['开奖日期'])
df = df.iloc[:,1:10]
'''滑块 : rangeslider , 选择器 : rangeselector'''
layout = {'title':{'text':'时间序列',
'x':0.5,
'font':{'color':'red','size':26}},
'xaxis':{'tickformat':'%Y-%m-%d',
'range':[df.开奖日期.min().replace(day=1),
df.开奖日期.max().replace(day=df.开奖日期.max().daysinmonth)],
'rangeselector':{'x':0.2,
'buttons':[{'label':'近一年','count':1,'step':'year','stepmode':'backward'},
{'label':'今年','count':1,'step':'year','stepmode':'todate'},
{'label':'近一月','count':1,'step':'month','stepmode':'backward'},
{'label':'all','step':'all'}]},
'rangeslider':{'visible':False}}}
fig = px.line(data_frame=df,x='开奖日期',y='蓝球',line_dash_sequence=['solid'],
markers=False,symbol_sequence=['circle'])
fig.update_layout(layout)
#plot(fig,image=None,filename='temp-plot.html')
iplot(fig,image=None,filename='plot_image')
import plotly.figure_factory as ff
谢谢大家 🌹
关于Plotly的内容,来源于《Python数据分析:基于Plotly的动态可视化绘图》
↩︎