您现在的位置是:首页 > 文章详情

什么是折线图?怎样用Python绘制?怎么用?终于有人讲明白了

日期:2020-01-07点击:490

云栖号:https://yqh.aliyun.com
第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策!

导读:数据分析时经常用到的折线图,你真的懂了吗?可以用来呈现哪些数据关系?在数据分析过程中可以解决哪些问题?怎样用Python绘制折线图?本文逐一为你解答。

作者:屈希峰,资深Python工程师,知乎多个专栏作者
来源:大数据DT(ID:hzdashuju)

image

01 概述

折线图(Line)是将排列在工作表的列或行中的数据进行绘制后形成的线状图形。折线图可以显示随时间(根据常用比例设置)而变化的连续数据,非常适用于显示在相等时间间隔下数据的趋势。

在折线图中,数据是递增还是递减、增减的速率、增减的规律(周期性、螺旋性等)、峰值等特征都可以清晰地反映出来。所以,折线图常用来分析数据随时间的变化趋势,也可用来分析多组数据随时间变化的相互作用和相互影响。

例如,可用来分析某类商品或是某几类相关的商品随时间变化的销售情况,从而进一步预测未来的销售情况。在折线图中,一般水平轴(x轴)用来表示时间的推移,并且间隔相同;而垂直轴(y轴)代表不同时刻的数据的大小。如图0所示。

image

图0 折线图

02 实例

折线图代码示例如下所示。

  • 代码示例1
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所示。

image

图1 代码示例1运行结果

代码示例1仍以最简单的方式绘制第一张折线图。line()方法的参数说明如下。

  • p.line(x, y, **kwargs)参数说明

1.x (:class:~bokeh.core.properties.NumberSpec ) : x坐标。
2.y (:class:~bokeh.core.properties.NumberSpec ) : y坐标。
3.line_alpha (:class:~bokeh.core.properties.NumberSpec ) : (default: 1.0) 轮廓线透明度。
4.line_cap ( :class:~bokeh.core.enums.LineCap ) : (default: 'butt') 线端。
5.line_color (:class:~bokeh.core.properties.ColorSpec ) : (default: 'black') 轮廓线颜色,默认:黑色。
6.line_dash (:class:~bokeh.core.properties.DashPattern ) : (default: []) 虚线,类型可以是序列,也可以是字符串('solid', 'dashed', 'dotted', 'dotdash', 'dashdot')。
7.line_dash_offset (:class:~bokeh.core.properties.Int ) : (default: 0) 虚线偏移。
8.line_join (:class:~bokeh.core.enums.LineJoin ) : (default: 'bevel')。
9.line_width (:class:~bokeh.core.properties.NumberSpec ) : (default: 1) 线宽。
10.name (:class:~bokeh.core.properties.String ) : 图元名称。
11.tags (:class:~bokeh.core.properties.Any ) :图元标签。
12.alpha (float) : 一次性设置所有线条的透明度。
13.color (Color) : 一次性设置所有线条的颜色。
14.source (ColumnDataSource) : Bokeh特有数据格式(类似于Pandas Dataframe)。
15.legend (str) : 图元的图例。
16.x_range_name (str) : x轴范围名称。
17.y_range_name (str) : y轴范围名称。
18.level (Enum) : 图元渲染级别。

  • 代码示例2
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所示。

image

图2 代码示例2运行结果

代码示例2第3行使用multi_line()方法,实现一次性绘制两条折线,同时,在参数中定义不同折线的颜色。如果使用Pandas Dataframe,则可以同时绘制不同列的数据。multi_line()方法的参数说明如下。

  • p.multi_line(xs, ys, **kwargs)参数说明

1.xs (:class:~bokeh.core.properties.NumberSpec ) :x坐标,列表。
2.ys (:class:~bokeh.core.properties.NumberSpec ) :y坐标,列表。

其他参数同line。

  • 代码示例3
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所示。

image

图3 代码示例3运行结果

代码示例3第13、15、16行使用line()方法逐一绘制折线,该方法的优点是基本数据清晰,可在不同线条绘制过程中直接定义图例。读者也可以使用multi_line()方法一次性绘制三条折线,然后再绘制折线上的数据点。同样,既可以在函数中预定义图例,也可以用Lengend方法单独进行定义,在后会对图例进行详细说明。

  • 代码示例4
1p.legend.location = "top_left" # 图例位于左上 2p.legend.click_policy="hide" # 点击图例显示、隐藏图形 3show(p) # 自行测试效果

运行结果如图4所示。

image

图4 代码示例4运行结果

代码示例4在代码示例3的基础上增加了图例的位置、显示或隐藏图形属性;通过点击图例,可实现图形的显示或隐藏,当折线数目较多或者颜色干扰阅读时,可以通过该方法实现对某一条折线数据的重点关注。这种通过图例、工具条、控件实现数据人机交互的可视化方式,正是Bokeh得以在GitHub火热的原因,建议在工作实践中予以借鉴。

  • 代码示例5
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所示。

image

图5 代码示例5运行结果

代码示例5第15、16行使用line()方法绘制两组不同颜色的曲线。

  • 代码示例6
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,返回概率密度函数 11 12# 生成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所示。

image

图6 代码示例6运行结果

代码示例6第19行中,生成绘图数据时,同时生成图例名称列表;第37、43行使用multi_line()方法一次性绘制6条曲线,并预定义图例。

  • 代码示例7
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所示。

image

图7 代码示例7运行结果

代码示例7与代码示例3相似,第10、19、21行对曲线的属性进行自定义,注意虚线的几种形式('solid', 'dashed', 'dotted', 'dotdash', 'dashdot'),读者可以自行替换测试。

  • 代码示例8
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='<font face="Arial" size="3">@$name{0.0} $name per 1,000 people in @year</font>') 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所示。

image

图8 代码示例8运行结果

代码示例8第22、23行通过line()方法绘制两条曲线,严格上讲这两条曲线并不是Bokeh时间序列的标准绘制方法。第17行定义了x轴刻度的间隔以及中间刻度数,读者可以尝试将num_minor_ticks=10的显示效果与图8进行对比;第18行定义了y轴的数据显示格式。

  • 代码示例9
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所示。

image

图9 代码示例9运行结果

代码示例9使用multi_line()方法在二维空间展示洛伦兹空间向量,示例中的数据生成稍微有点复杂,可以直观感受可视化之下的数据之美,有兴趣的读者可以深入了解。

  • 代码示10
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所示。

image

图10 代码示10运行结果

代码示例10增加了Bokeh控件复选框,第12、13、14行使用line()方法绘制3条曲线;第16行定义复选框,并在18行定义回调函数,通过该回调函数控制3条曲线的可视状态;第24行将复选框、绘图并在一行进行显示。

  • 代码示例11
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所示。

image

图11 代码示例11运行结果

代码示例11增加点击曲线的交互效果,第20、21、22行使用line()方法绘制3条曲线;第26行定义曲线再次被点击时的效果:图11中左下方会动态显示当前选中的是哪条颜色的曲线。

  • 代码示例12
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所示。

image

图12 代码示例12运行结果

代码示例12使用models接口进行曲线绘制,注意第10、17、20行的绘制方法,这种绘图方式在实践中基本很少用到,仅作了解。

原文发布时间:2020-01-06
本文作者:屈希峰
本文来自阿里云云栖号合作伙伴“大数据DT”,了解相关信息可以关注“大数据DT

云栖号:https://yqh.aliyun.com
第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策!

原文链接:https://yq.aliyun.com/articles/742093
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章