您現在的位置是:首頁 > 垂釣

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

  • 由 華章科技 發表于 垂釣
  • 2022-02-03
簡介append(scale)  20# 線條顏色  21mass_spec[‘color’] = Viridis6  22# 畫布引數  23figure_opts = dict(plot_width=450, plot_height=300

折線是什麼

導讀:資料分析時經常用到的折線圖,你真的懂了嗎?可以用來呈現哪些資料關係?在資料分析過程中可以解決哪些問題?怎樣用Python繪製折線圖?本文逐一為你解答。

作者:屈希峰,資深Python工程師,知乎多個專欄作者

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

01 概述

折線圖(Line)是將排列在工作表的列或行中的資料進行繪製後形成的線狀圖形。折線圖可以顯示隨時間(根據常用比例設定)而變化的連續資料,非常適用於顯示在相等時間間隔下資料的趨勢。

在折線圖中,資料是遞增還是遞減、增減的速率、增減的規律(週期性、螺旋性等)、峰值等特徵都可以清晰地反映出來。所以,

折線圖常用來分析資料隨時間的變化趨勢,也可用來分析多組資料隨時間變化的相互作用和相互影響。

例如,可用來分析某類商品或是某幾類相關的商品隨時間變化的銷售情況,從而進一步預測未來的銷售情況。在折線圖中,一般水平軸(x軸)用來表示時間的推移,並且間隔相同;而垂直軸(y軸)代表不同時刻的資料的大小。如圖0所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖0 折線圖

02 例項

折線圖程式碼示例如下所示。

程式碼示例①

1# 資料  2x = [1, 2, 3, 4, 5, 6, 7]  3y = [6, 7, 2, 4, 5, 10, 4]  4# 畫布:座標軸標籤,畫布大小  5p = figure(title=“line example”, x_axis_label=‘x’, y_axis_label=‘y’, width=400, height=400)  6# 繪圖:資料、圖例、線寬  7p。line(x, y, legend=“Temp。”, line_width=2)  # 折線  8# 顯示9show(p)

執行結果如圖1所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖1 程式碼示例①執行結果

程式碼示例①仍以最簡單的方式繪製第一張折線圖。line()方法的引數說明如下。

p.line(x, y, **kwargs)引數說明

x

(:class:`~bokeh。core。properties。NumberSpec` ) : x座標。

y

(:class:`~bokeh。core。properties。NumberSpec` ) : y座標。

line_alpha

(:class:`~bokeh。core。properties。NumberSpec` ) : (default: 1。0) 輪廓線透明度。

line_cap

( :class:`~bokeh。core。enums。LineCap` ) : (default: ‘butt’) 線端。

line_color

(:class:`~bokeh。core。properties。ColorSpec` ) : (default: ‘black’) 輪廓線顏色,預設:黑色。

line_dash

(:class:`~bokeh。core。properties。DashPattern` ) : (default: []) 虛線,型別可以是序列,也可以是字串(‘solid’, ‘dashed’, ‘dotted’, ‘dotdash’, ‘dashdot’)。

line_dash_offset

(:class:`~bokeh。core。properties。Int` ) : (default: 0) 虛線偏移。

line_join

(:class:`~bokeh。core。enums。LineJoin` ) : (default: ‘bevel’)。

line_width

(:class:`~bokeh。core。properties。NumberSpec` ) : (default: 1) 線寬。

name

(:class:`~bokeh。core。properties。String` ) : 圖元名稱。

tags

(:class:`~bokeh。core。properties。Any` ) :圖元標籤。

alpha

(float) : 一次性設定所有線條的透明度。

color

(Color) : 一次性設定所有線條的顏色。

source

(ColumnDataSource) : Bokeh特有資料格式(類似於Pandas Dataframe)。

legend

(str) : 圖元的圖例。

x_range_name

(str) : x軸範圍名稱。

y_range_name

(str) : y軸範圍名稱。

level

(Enum) : 圖元渲染級別。

程式碼示例②

1p = figure(plot_width=400, plot_height=400)  2# 線段x、y位置點均為列表;兩段線的顏色、透明度、線寬  3p。multi_line([[1, 3, 2], [3, 4, 6, 6]], [[2, 1, 4], [4, 7, 8, 5]],  4color=[“firebrick”, “navy”], alpha=[0。8, 0。3], line_width=4)  # 多條折(曲)線5show(p)

執行結果如圖2所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖2 程式碼示例②執行結果

程式碼示例②第3行使用multi_line()方法,實現一次性繪製兩條折線,同時,在引數中定義不同折線的顏色。如果使用Pandas Dataframe,則可以同時繪製不同列的資料。multi_line()方法的引數說明如下。

p.multi_line(xs, ys, **kwargs)引數說明

xs

(:class:`~bokeh。core。properties。NumberSpec` ) :x座標,列表。

ys

(:class:`~bokeh。core。properties。NumberSpec` ) :y座標,列表。

其他引數同line。

程式碼示例③

1# 準備資料   2x = [0。1, 0。5, 1。0, 1。5, 2。0, 2。5, 3。0]   3y0 = [i**2 for i in x]   4y1 = [10**i for i in x]   5y2 = [10**(i**2) for i in x]   6# 建立畫布   7p = figure(   8      tools=“pan,box_zoom,reset,save”,   9      y_axis_type=“log”, title=“log axis example”,  10      x_axis_label=‘sections’, y_axis_label=‘particles’,  11      width=700, height=350)  12# 增加圖層,繪圖  13p。line(x, x, legend=“y=x”)  14p。circle(x, x, legend=“y=x”, fill_color=“white”, size=8)  15p。line(x, y0, legend=“y=x^2”, line_width=3)  16p。line(x, y1, legend=“y=10^x”, line_color=“red”)  17p。circle(x, y1, legend=“y=10^x”, fill_color=“red”, line_color=“red”, size=6) 18p。line(x, y2, legend=“y=10^x^2”, line_color=“orange”, line_dash=“4 4”)  19# 顯示  20show(p)

執行結果如圖3所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖3 程式碼示例③執行結果

程式碼示例③第13、15、16行使用line()方法逐一繪製折線,該方法的優點是基本資料清晰,可在不同線條繪製過程中直接定義圖例。讀者也可以使用multi_line()方法一次性繪製三條折線,然後再繪製折線上的資料點。同樣,既可以在函式中預定義圖例,也可以用Lengend方法單獨進行定義,在後會對圖例進行詳細說明。

程式碼示例④

1p。legend。location = “top_left”  # 圖例位於左上  2p。legend。click_policy=“hide” # 點選圖例顯示、隱藏圖形  3show(p)  # 自行測試效果

執行結果如圖4所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖4 程式碼示例④執行結果

程式碼示例④在程式碼示例③的基礎上增加了圖例的位置、顯示或隱藏圖形屬性;透過點選圖例,可實現圖形的顯示或隱藏,當折線數目較多或者顏色干擾閱讀時,可以透過該方法實現對某一條折線資料的重點關注。這種透過圖例、工具條、控制元件實現資料人機互動的視覺化方式,正是Bokeh得以在GitHub火熱的原因,建議在工作實踐中予以借鑑。

程式碼示例⑤

1# 資料   2import numpy as np   3x = np。linspace(0, 4*np。pi, 200)   4y1 = np。sin(x)   5y2 = np。cos(x)   6# 將y1+—0。9範圍外的資料設定為無窮大   7y1[y1>+0。9] = +np。inf   8y1[y1<-0。9] = -np。inf   9# 將y2+—0。9範圍外的資料採用掩碼陣列或NAN值替換  10y2 = np。ma。masked_array(y2, y2<-0。9)  11y2[y2>0。9] = np。nan  12# 圖層  13p = figure(title=“lines with missing/inf values”)  14# 繪圖x,y1  15p。line(x, y1, color=“firebrick”, line_width=2)  # 磚紅色  16# 繪圖x,y2  17p。line(x, y2, color=“blue”, line_width=2)  # 藍色  18show(p)

執行結果如圖5所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖5 程式碼示例⑤執行結果

程式碼示例⑤第15、16行使用line()方法繪製兩組不同顏色的曲線。

程式碼示例⑥

1import numpy as np   2from collections import defaultdict   3from scipy。stats import norm   4from bokeh。models import HoverTool, TapTool   5from bokeh。layouts import gridplot   6from bokeh。palettes import Viridis6   7# 資料   8mass_spec = defaultdict(list)  #defaultdict類的初始化函式接受一個list型別作為引數,當所訪問的鍵不存在時,可以例項化一個值作為預設值   9RT_x = np。linspace(118, 123, num=50)  10norm_dist = norm(loc=120。4)。pdf(RT_x)  # loc均值;pdf輸入x,返回機率密度函式  1112# 生成6組高斯分佈的曲線  13for scale, mz in [(1。0, 83), (0。9, 55), (0。6, 98), (0。4, 43), (0。2, 39), (0。12, 29)]:  14       mass_spec[“RT”]。append(RT_x)  15       mass_spec[“RT_intensity”]。append(norm_dist * scale)   16       mass_spec[“MZ”]。append([mz, mz])  17       mass_spec[“MZ_intensity”]。append([0, scale])  18       mass_spec[‘MZ_tip’]。append(mz)  19       mass_spec[‘Intensity_tip’]。append(scale)  20# 線條顏色  21mass_spec[‘color’] = Viridis6  22# 畫布引數  23figure_opts = dict(plot_width=450, plot_height=300)  24hover_opts = dict(  25    tooltips=[(‘MZ’, ‘@MZ_tip’), (‘Rel Intensity’, ‘@Intensity_tip’)],  # 滑鼠懸停在曲線上動態顯示資料  26    show_arrow=False,  27    line_policy=‘next’  28)  29line_opts = dict(  30    line_width=5, line_color=‘color’, line_alpha=0。6,  31    hover_line_color=‘color’, hover_line_alpha=1。0,  32    source=mass_spec  # 線條資料  33)  34# 畫布1  35rt_plot = figure(tools=[HoverTool(**hover_opts), TapTool()], **figure_opts)  36# 同時繪製多條折(曲)線  37rt_plot。multi_line(xs=‘RT’, ys=‘RT_intensity’, legend=“Intensity_tip”, **line_opts)  38# x,y軸標籤  39rt_plot。xaxis。axis_label = “Retention Time (sec)”  40rt_plot。yaxis。axis_label = “Intensity”  41# 畫布2  42mz_plot = figure(tools=[HoverTool(**hover_opts), TapTool()], **figure_opts)  43mz_plot。multi_line(xs=‘MZ’, ys=‘MZ_intensity’, legend=“Intensity_tip”, **line_opts)  44mz_plot。legend。location = “top_center”  45mz_plot。xaxis。axis_label = “MZ”  46mz_plot。yaxis。axis_label = “Intensity”  47# 顯示  48show(gridplot([[rt_plot, mz_plot]]))

執行結果如圖6所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖6 程式碼示例⑥執行結果

程式碼示例⑥第19行中,生成繪圖資料時,同時生成圖例名稱列表;第37、43行使用multi_line()方法一次性繪製6條曲線,並預定義圖例。

程式碼示例⑦

1import numpy as np   2# 資料   3x = np。linspace(0。1, 5, 80)   4# 畫布   5p = figure(title=“log axis example”, y_axis_type=“log”,   6                    x_range=(0, 5), y_range=(0。001, 10**22),   7                    background_fill_color=“#fafafa”)   8# 繪圖   9p。line(x, np。sqrt(x), legend=“y=sqrt(x)”,  10            line_color=“tomato”, line_dash=“dashed”)  11p。line(x, x, legend=“y=x”)  12p。circle(x, x, legend=“y=x”)  13p。line(x, x**2, legend=“y=x**2”)  14p。circle(x, x**2, legend=“y=x**2”,  15            fill_color=None, line_color=“olivedrab”)  16p。line(x, 10**x, legend=“y=10^x”,  17            line_color=“gold”, line_width=2)  18p。line(x, x**x, legend=“y=x^x”,  19            line_dash=“dotted”, line_color=“indigo”, line_width=2)  20p。line(x, 10**(x**2), legend=“y=10^(x^2)”,  21            line_color=“coral”, line_dash=“dotdash”, line_width=2)  22# 其他  23p。legend。location = “top_left”  24# 顯示  25show(p)

執行結果如圖7所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖7 程式碼示例⑦執行結果

程式碼示例⑦與程式碼示例③相似,第10、19、21行對曲線的屬性進行自定義,注意虛線的幾種形式(‘solid’, ‘dashed’, ‘dotted’, ‘dotdash’, ‘dashdot’),讀者可以自行替換測試。

程式碼示例⑧

1from bokeh。models import ColumnDataSource, NumeralTickFormatter, SingleIntervalTicker 2from bokeh。sampledata。us_marriages_divorces import data   3# 資料   4data = data。interpolate(method=‘linear’, axis=0)。ffill()。bfill()   5source = ColumnDataSource(data=dict(   6       year=data。Year。values,   7       marriages=data。Marriages_per_1000。values,   8       divorces=data。Divorces_per_1000。values,   9))  10# 工具條  11TOOLS = ‘pan,wheel_zoom,box_zoom,reset,save’  12# 畫布  13p = figure(tools=TOOLS, plot_width=800, plot_height=500,  14              tooltips=‘@$name{0。0} $name per 1,000 people in @year’)  15# 其他自定義屬性  16p。hover。mode = ‘vline’  17p。xaxis。ticker = SingleIntervalTicker(interval=10, num_minor_ticks=0)  18p。yaxis。formatter = NumeralTickFormatter(format=‘0。0a’)  19p。yaxis。axis_label = ‘# per 1,000 people’  20p。title。text = ‘144 years of marriage and divorce in the U。S。’  21# 繪圖  22p。line(‘year’, ‘marriages’, color=‘#1f77b4’, line_width=3, source=source, name=“marriages”)  23p。line(‘year’, ‘divorces’, color=‘#ff7f0e’, line_width=3, source=source, name=“divorces”)  24# 顯示  25show(p)

執行結果如圖8所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖8 程式碼示例⑧執行結果

程式碼示例⑧第22、23行透過line()方法繪製兩條曲線,嚴格上講這兩條曲線並不是Bokeh時間序列的標準繪製方法。第17行定義了x軸刻度的間隔以及中間刻度數,讀者可以嘗試將num_minor_ticks=10的顯示效果與圖8進行對比;第18行定義了y軸的資料顯示格式。

程式碼示例⑨

1import numpy as np   2from scipy。integrate import odeint   3# 資料   4sigma = 10   5rho = 28   6beta = 8。0/3   7theta = 3 * np。pi / 4   8# 洛倫茲空間向量點生成函式   9def lorenz(xyz, t):  10      x, y, z = xyz  11      x_dot = sigma * (y - x)  12      y_dot = x * rho - x * z - y  13      z_dot = x * y - beta* z  14      return [x_dot, y_dot, z_dot]  15initial = (-10, -7, 35)  16t = np。arange(0, 100, 0。006)  17solution = odeint(lorenz, initial, t)  18x = solution[:, 0]  19y = solution[:, 1]  20z = solution[:, 2]  21xprime = np。cos(theta) * x - np。sin(theta) * y  22# 調色  23colors = [“#C6DBEF”, “#9ECAE1”, “#6BAED6”, “#4292C6”, “#2171B5”, “#08519C”, “#08306B”,]  24# 畫布  25p = figure(title=“Lorenz attractor example”, background_fill_color=“#fafafa”)  26# 繪圖 洛倫茲空間向量 27p。multi_line(np。array_split(xprime, 7), np。array_split(z, 7),  28             line_color=colors, line_alpha=0。8, line_width=1。5)  29# 顯示  30show(p)

執行結果如圖9所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖9 程式碼示例⑨執行結果

程式碼示例⑨使用multi_line()方法在二維空間展示洛倫茲空間向量,示例中的資料生成稍微有點複雜,可以直觀感受視覺化之下的資料之美,有興趣的讀者可以深入瞭解。

程式碼示例⑩

1import numpy as np   2from bokeh。layouts import row   3from bokeh。palettes import Viridis3   4from bokeh。models import CheckboxGroup, CustomJS   5# 資料   6x = np。linspace(0, 4 * np。pi, 100)   7# 畫布   8p = figure()   9# 折線屬性  10props = dict(line_width=4, line_alpha=0。7)  11# 繪圖  12l0 = p。line(x, np。sin(x), color=Viridis3[0], legend=“Line 0”, **props)  13l1 = p。line(x, 4 * np。cos(x), color=Viridis3[1], legend=“Line 1”, **props)  14l2 = p。line(x, np。tan(x), color=Viridis3[2], legend=“Line 2”, **props)  15# 複選框啟用顯示  16checkbox = CheckboxGroup(labels=[“Line 0”, “Line 1”, “Line 2”],  17                         active=[0, 1, 2], width=100)  18checkbox。callback = CustomJS(args=dict(l0=l0, l1=l1, l2=l2, checkbox=checkbox), code=“”“ 19l0。visible = 0 in checkbox。active; 20l1。visible = 1 in checkbox。active; 21l2。visible = 2 in checkbox。active; 22”“”)  23# 新增圖層  24layout = row(checkbox, p)  25# 顯示  26show(layout)

執行結果如圖10所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖10 程式碼示例⑩執行結果

程式碼示例⑩增加了Bokeh控制元件複選框,第12、13、14行使用line()方法繪製3條曲線;第16行定義複選框,並在18行定義回撥函式,透過該回調函式控制3條曲線的可視狀態;第24行將複選框、繪圖並在一行進行顯示。

程式碼示例⑪

1from bokeh。models import TapTool, CustomJS, ColumnDataSource   2# 資料   3t = np。linspace(0, 0。1, 100)   4# 回撥函式   5code = “”“  6// cb_data = {geometries: 。。。, source: 。。。}  7const view = cb_data。source。selected。get_view();  8const data = source。data;  9if (view) { 10      const color = view。model。line_color; 11      data[‘text’] = [‘Selected the ’ + color + ‘ line’]; 12      data[‘text_color’] = [color]; 13      source。change。emit(); 14} 15”“”  16source = ColumnDataSource(data=dict(text=[‘No line selected’], text_color=[‘black’]))  17# 畫布  18p = figure(width=600, height=500)  19# 繪圖  20l1 = p。line(t, 100*np。sin(t*50), color=‘goldenrod’, line_width=30)  21l2 = p。line(t, 100*np。sin(t*50+1), color=‘lightcoral’, line_width=20)  22l3 = p。line(t, 100*np。sin(t*50+2), color=‘royalblue’, line_width=10)  23# 文字,注意選擇線條時候的文字變化  24p。text(0, -100, text_color=‘text_color’, source=source)  25# 呼叫回撥函式進行動態互動  26p。add_tools(TapTool(callback=CustomJS(code=code, args=dict(source=source))))  27# 顯示  28show(p)

執行結果如圖11所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖11 程式碼示例⑪執行結果

程式碼示例⑪增加點選曲線的互動效果,第20、21、22行使用line()方法繪製3條曲線;第26行定義曲線再次被點選時的效果:圖11中左下方會動態顯示當前選中的是哪條顏色的曲線。

程式碼示例⑫

1import numpy as np   2from bokeh。models import ColumnDataSource, Plot, LinearAxis, Grid   3from bokeh。models。glyphs import Line   4# 資料   5N = 30   6x = np。linspace(-2, 2, N)   7y = x**2   8source = ColumnDataSource(dict(x=x, y=y))   9# 畫布  10plot = Plot(  11       title=None, plot_width=300, plot_height=300,  12#         min_border=0,   13#         toolbar_location=None  14)  15# 繪圖  16glyph = Line(x=“x”, y=“y”, line_color=“#f46d43”, line_width=6, line_alpha=0。6)17plot。add_glyph(source, glyph)  18# x軸單獨設定(預設)  19xaxis = LinearAxis()  20plot。add_layout(xaxis, ‘below’)  21# y軸單獨設定(預設)  22yaxis = LinearAxis()  23plot。add_layout(yaxis, ‘left’)  24# 座標軸刻度  25plot。add_layout(Grid(dimension=0, ticker=xaxis。ticker))  26plot。add_layout(Grid(dimension=1, ticker=yaxis。ticker))  27# 顯示  28show(plot)

執行結果如圖12所示。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

▲圖12 程式碼示例⑫執行結果

程式碼示例⑫使用models介面進行曲線繪製,注意第10、17、20行的繪製方法,這種繪圖方式在實踐中基本很少用到,僅作了解。

本文摘編自《Python資料視覺化:基於Bokeh的視覺化繪圖》,經出版方授權釋出。

Python資料視覺化:一文看懂折線圖繪製與使用,值得收藏

延伸閱讀《Python資料視覺化》

推薦語:

從圖形繪製、資料動態展示、Web互動等維度全面講解Bokeh功能和使用,不含複雜資料處理和演算法,深入淺出,適合零基礎入門,包含大量案例。

Top