python画图:Plotly学习笔记

本次笔记内容

  • plotly基本用法
  • 基本Scatter示例:go.Scatter(),按连续型/分类型变量着色
  • 基本Scatter示例:px(),按连续型/分类型变量着色
  • colorscale
  • subplots和facet
  • 各种layout:
    lengend字号size, 图标大小,hoverlabel大小;
    坐标轴字号大小,倾斜(不是斜体,是倾斜角度);
    网格线的隐藏;
    将x轴放在图上方,y轴放在图右边;
  • 注意

plotly基本用法

每一个trace就像一个独立的图层,互不干扰。data=[trace1, trace2...]将这些图层叠加在一起。
layout定义了data提供的信息之外的东西,比如plot title, 坐标轴的设置

import plotly
import plotly.graph_objects as go
trace1 = go.Scatter(...)
trace2 = go.Scatter(...)
layout1 = go.Layout(...)
fig = go.Figure(data=[trace1,trace2],
                layout=layout1)
fig.show() # 直接plot出来

# or 保存为.html格式的文件
plotly.offline.plot(dict(data=[trace1,trace2]), filename = 'XXX.html')

基本Scatter示例:go.Scatter(),按连续型变量着色

import plotly.express as px
import plotly.graph_objects as go
import plotly

tips = px.data.tips() # 用px里的示例数据
tips.head() #看一下
total_bill  tip sex smoker  day time    size
0   16.99   1.01    Female  No  Sun Dinner  2
1   10.34   1.66    Male    No  Sun Dinner  3
2   21.01   3.50    Male    No  Sun Dinner  3
3   23.68   3.31    Male    No  Sun Dinner  2
4   24.59   3.61    Female  No  Sun Dinner  4

trace_tip = go.Scatter(x=tips.total_bill.tolist(),
                       y=tips.tip.tolist(),
                       mode='markers+text',
                       # mode决定图上出现点,线,text等的组合形式
                       name = 'trace_tip',
                       marker=dict(color=tips['size'].tolist(), #  上色类别
                                   colorscale='Viridis',  # 指定颜色
                                   showscale=True,
                                   size=[i*10 for i in tips['size'].tolist()]),  #点大小
                       # showlegend=True,
                       text=tips['sex'].tolist(),
                       textposition='bottom center',
                       textfont=dict(size=18,color='LightSeaGreen'))
                       

# plotly.offline.plot(dict(data=[trace_tip]),filename='plot.html')
fig = go.Figure(data=[trace_tip]) 
# 如果在这个基础上接着画,那就[trace_tip1, trace_tip2...]
fig.show()

基本Scatter实例:go.Scatter(),按分类型变量着色

set(tips.day.tolist()) # {'Fri', 'Sat', 'Sun', 'Thur'}
# 这个set里每个类别,都要建立一个trace,4个trace叠在一起,才能交互式的点击选择各个类别
color_day_dict = dict(zip(set(tips.day.tolist()),
                          plotly.colors.colorbrewer.Set1))
# 设置一个颜色的对应关系

trace0 = [] #...还要写for,真麻烦啊=_=
for i in set(tips.day.tolist()):
    tips_temp = tips.loc[tips['day']==i,:] #记得要Slice一下input data
    trace0.append(go.Scatter(x=tips_temp.total_bill.tolist(),
                             y=tips_temp.tip.tolist(),
                             mode='markers',
                             name = i,
                             marker=dict(color=color_day_dict[i],
                                         size=10)))
fig = go.Figure(data=trace0)
fig.show() 

基本Scatter示例:px(),按连续型变量着色

tips['size10'] = tips['size']*10

fig = px.scatter(tips,x='total_bill',y='tip',size='size10',color='size',size_max=40,
                 color_continuous_scale=px.colors.sequential.Viridis,text='sex')
# 对于text的颜色大小位置,在update_trace里设置
fig.update_traces(textposition='bottom center',
                  textfont=dict(size=18,
                                color='LightSeaGreen'))

fig.write_html('plot.html')  # 保存为html格式
# fig.show()

基本Scatter示例:px(),按分类型变量着色

tips['size_fixed'] = 10 
# 在px中不能指定size=10,一定要是出现在input dataframe中的列才行

fig = px.scatter(tips,x='total_bill',
                 y='tip',color='day',
                 color_discrete_sequence=plotly.colors.colorbrewer.Set1)   
                 # color_discrete_sequence直接指定颜色set,不能指定颜色和类别的对应关系

fig = px.scatter(tips,x='total_bill',
                 y='tip',color='day',
                 color_discrete_map=color_day_dict,
                 # 用字典指定颜色和类别的对应关系 
                 size='size_fixed')  # size_fixed,是出现在tips这个dataframe中的column
fig.show()

colorscale

可以选择build-in的colorscale,也可以自己定义。在数据分布很极端的情况下,均匀的build-in color可能不太适用。
(不过build-in颜色盘已经很美了,能用尽量用)

# 通过colorscale自定义颜色区间对应关系,即0-65%的值会根据rgb(231,231,230) --- rgb(0,25,225)这个区间来着色。
trace_tip = go.Scatter(x=tips.total_bill.tolist(),
                       y=tips.tip.tolist(),
                       mode='markers',
                       marker=dict(color=tips['total_bill'].tolist(), #  上色类别
                                   showscale=True,
                                   size=10,
                                   colorscale=[[0,'rgb(231,231,230)'],
                                               [0.65,'rgb(0,25,225)'], # 当然你也可以做成均匀的颜色分布
                                               [0.75,'rgb(0,152,255)'],
                                               [0.85,'rgb(44,255,150)'],
                                               [0.95,'rgb(255,234,0)'],
                                               [1,'rgb(255,0,0)']],
                                   colorbar=dict(title='you_define'))  # colorbar上的title
                       )
                       
fig = go.Figure(data=[trace_tip]) 
fig.update_layout(autosize=False, height=600,width=800)
# 设置图片大小
fig.show()

参考https://plot.ly/python/colorscales/

subplots和facet

plotly express暂时(2020年)没有subplots, 可以使用facet分面做出subplots的效果。那似乎是不能把来源不同的图拼起来的。plotly.graph_objects可以整个subplots出来,将不同来源的plots拼在一起,还可以设置它们的位置。

# 比方说
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

px.histogram(df,x='value',color='XXX',
             color_discrete_sequence=px.colors.qualitative.Set1,
             facet_col='variable', facet_col_wrap=4) # 用variable来分面,排到4个图就换一行
# 也就是说用于facet的变量必须也在df这个input dataframe里
fig = make_subplots(1,3)  # 1 row, 3 cols
fig.add_trace(go.Scatter(....))  # 用个for来add_trace更合适

各种layout

# 还是tips这个数据集
color_day_dict = dict(zip(set(tips.day.tolist()),plotly.colors.colorbrewer.Set1))

trace0 = []
for i in set(tips.day.tolist()):
    tips_temp = tips.loc[tips['day']==i,:]
    trace0.append(go.Scatter(x=tips_temp.total_bill.tolist(),
                             y=tips_temp.tip.tolist(),
                             mode='markers',
                             name = i,
                             marker=dict(color=color_day_dict[i],
                                         size=10)))

fig = go.Figure(data=trace0)

fig.update_layout(height=500, width=800, #设置图大小
                  font=dict(size=20),  # 字体大小
                  legend={'font':dict(size=22),  # legend字体大小 
                          'itemsizing': 'constant',}, # legend图标大小
                  hoverlabel=dict(font=dict(size=20))) #hoverlabel大小

fig.update_xaxes(tickangle=45)  # 设置X轴字符倾斜45度
fig['layout']['yaxis']['showgrid'] = False  # Y轴不显示网格
fig['layout']['yaxis']['side'] = 'right'  #将Y轴放置在右边

fig['layout']['xaxis']['showgrid'] = False  # 设置X轴不显示网格
fig['layout']['xaxis']['side'] = 'top'  # 将X轴放置在顶部

fig.show()

注意:

  1. 如果用jupyter lab, 需要安装一些jupyter lab及其相关支持,follow官方的步骤:
  2. 超级详细的reference: 每个attribue都是什么意思
    比方说go.Scatter(mode=...)中有几个mode选项,分别有什么效果,都非常详细。真的太详细了,我喜极而泣T_T
  3. plotly本质上并不是为publish服务的,也不是统计分析友好型的可视化工具。但是interactive的模式能帮助我们更好的了解数据背后的东西(以及更加好看和酷炫)。就分析报告的出具,为发表paper准备的标准化制图而言,可能还是R的ggplot2, ggpubr更加方便顺手一些。对于数据量大,层次丰富,研究目的不那么明确的数据,plotly可能更加便于发现问题。当然还是要根据需求选择工具。
  4. plotly express,拉到最后看plotly自带调色板
  5. 虽然plotly express和R的ggplot2惊人相似,但是express似乎并没有把所有可调节的东西纳入函数里。不像ggplot2的万物皆可调。比如ggplot2可以通过+theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1...))来调节X轴数字字体大小,距离轴的距离,倾斜角度等。plotly我暂时没找到除了update_trace, update_layout之外的,可以在函数内实现的方法。(当然可能是文档看少了)
  6. 一开始我对express是嫌弃的,因为px.XXX()中的参数都需要出现在input data的column names里面,不能在一个函数里解决所有问题,觉得十分麻烦。后来我反思了一下,觉得我是被R的ggplot2盖楼式画图给惯坏了。如果对于自己要画什么图非常明确,且input数据可以全部规整到一个dataframe里,那用express是非常方便的。
  7. figure label: https://plot.ly/python/figure-labels/
    axis label: https://plot.ly/python/axes/#set-axis-label-rotation-and-font
    hover text: https://plot.ly/python/hover-text-and-formatting/
    resize hover info box: https://community.plot.ly/t/re-size-hover-info-box/955
    hover info box: https://github.com/plotly/plotly.js/issues/102
  8. plotly express 小贴士
px.box(df, x='...', y = '...', color = '...', 
       category_orders = dict(X_content = ['A','B','C']))
      # 用于将X轴自由sort
  1. 友情链接:
    plotly绘图说明
    plotly 4.0自来水公司通告(可视化python模块推荐)

你可能感兴趣的:(python画图:Plotly学习笔记)