python畫圖:Plotly學習筆記

本次筆記內容

  • plotly基本用法
  • 基本Scatter示例:go.Scatter(),按連續(xù)型/分類型變量著色
  • 基本Scatter示例:px(),按連續(xù)型/分類型變量著色
  • 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(),按連續(xù)型變量著色

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

tips = px.data.tips() # 用px里的示例數(shù)據
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決定圖上出現(xiàn)點,線,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(),按連續(xù)型變量著色

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,一定要是出現(xiàn)在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,是出現(xiàn)在tips這個dataframe中的column
fig.show()

colorscale

可以選擇build-in的colorscale,也可以自己定義。在數(shù)據分布很極端的情況下,均勻的build-in color可能不太適用。
(不過build-in顏色盤已經很美了,能用盡量用)

# 通過colorscale自定義顏色區(qū)間對應關系,即0-65%的值會根據rgb(231,231,230) --- rgb(0,25,225)這個區(qū)間來著色。
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這個數(shù)據集
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服務的,也不是統(tǒng)計分析友好型的可視化工具。但是interactive的模式能幫助我們更好的了解數(shù)據背后的東西(以及更加好看和酷炫)。就分析報告的出具,為發(fā)表paper準備的標準化制圖而言,可能還是R的ggplot2, ggpubr更加方便順手一些。對于數(shù)據量大,層次豐富,研究目的不那么明確的數(shù)據,plotly可能更加便于發(fā)現(xiàn)問題。當然還是要根據需求選擇工具。
  4. plotly express,拉到最后看plotly自帶調色板
  5. 雖然plotly express和R的ggplot2驚人相似,但是express似乎并沒有把所有可調節(jié)的東西納入函數(shù)里。不像ggplot2的萬物皆可調。比如ggplot2可以通過+theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1...))來調節(jié)X軸數(shù)字字體大小,距離軸的距離,傾斜角度等。plotly我暫時沒找到除了update_trace, update_layout之外的,可以在函數(shù)內實現(xiàn)的方法。(當然可能是文檔看少了)
  6. 一開始我對express是嫌棄的,因為px.XXX()中的參數(shù)都需要出現(xiàn)在input data的column names里面,不能在一個函數(shù)里解決所有問題,覺得十分麻煩。后來我反思了一下,覺得我是被R的ggplot2蓋樓式畫圖給慣壞了。如果對于自己要畫什么圖非常明確,且input數(shù)據可以全部規(guī)整到一個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模塊推薦)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容