从零开始学Python可视化(一): 极速上手

首先,不能马上让人上手的教程,就是耍流氓。

我们都知道,matplotlib是Python下一个极其强大的作图库。但是它虽然强大,却有着陡峭的学习曲线,想要用它来灵活地作图需要花费大量的学习时间,这也是为什么近年来基于matplotlib封装的Seaborn等作图库迅速流行起来的原因。

我们希望能迅速上手一个工具并画出美观而有说服力、有解释力的图形,而不是花费大量的时间却仍然飘在云里雾里。

matplotlib有两种语言风格,一种是沿袭自MatLab的命令式风格,一种是Python的面向对象风格。不同的作图风格有时会让我们感到混乱,这也在无形中增加了我们的学习难度。不过我们今天不是来讨论风格优劣的,我们今天的目的是熟悉matplotlib的基本作图函数,以达到快速上手Python可视化的目的。

今天,我们先抛却又臭又长的官方文档,抛却庞大的作图知识体系,尝试在30分钟内掌握基本的作图能力。

我们先从最常用的作图函数以及样式调整函数学起,其他的让它们先玩儿去吧。


欢迎大家关注我的个人博客【数洞】 【备用站】

1. plot()

plot()函数包含了很多基础的绘图功能,这里我们用它来绘制线图,用以展现数据的变化趋势。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 1000)
y = np.sin(x)

# 使用plt.plot()绘图
# lw ~ line width,用于设置线条宽度
# '-r'是说线条使用正常的连续曲线,颜色使用红色
# label设置线条的标签,我们会在图例中看到它
plt.plot(x, y, ls='-r', lw=2, label='sin(x)')
plt.legend()
plt.show()
image

2. scatter()

scatter()函数用以绘制散点图,我们常用它来观察变量间的相关性。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.random.rand(100)

# 使用plt.scatter()绘图
# c ~ color,用于设置颜色
# alpha用于控制透明度
plt.scatter(x, y, c='g', alpha=0.5, label='scatters')
plt.legend()
plt.show()
image

3. xlim() / ylim()

这两个函数用于设置坐标轴的数值显示范围。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.random.rand(100)

# 使用scatter绘图
plt.scatter(x, y, label='scatters')
plt.legend()

# 使用xlim()/ylim()调整坐标轴
# 我们需要上下(左右)两个边界的数值
plt.xlim(2, 10)
plt.ylim(-0.2, 1.2)
plt.show()

可以看到,虽然我们数据的范围是x ∈ [0, 10], y ∈ [0, 1],但在我们的强烈要求下,图片上只展示出了其中的一部分。

image

4. xlabel() / ylabel()

顾名思义,这两个函数用于设置坐标轴的标签。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
# ls ~ line style,用于设置线条类型
plt.plot(x, y, ls='-.', lw=2, c='g', label='sin(x)')
plt.legend()

# 使用xlim()/ylim()调整坐标轴
plt.xlabel('x-axis')
plt.ylabel('y-axis')
plt.show()
image

5. grid()

就喜欢这么直白的命名,grid()函数正是用于设置图形中的网格线。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()

# 使用grid()调整网格线
# linestyle用于设置网格的线条类型,color用于设置网格的线条颜色
plt.grid(linestyle=':', color='r')

plt.show()

啊,好丑。


image

6. axhline() / axvline()

ax ~ axis
h ~ horizontal,水平的
v ~ vertical,垂直的

组合起来看,我们可以猜到,这两个函数分别用于设置水平参考线和垂直参考线。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()

# 这里的参数跟之前几个函数的参数类似,不再赘述
plt.axhline(y=0, c='r', ls='--', lw=2)
plt.axvline(x=5, c='g', ls='-.', lw=2)

plt.show()
image

7. axhspan() / axvspan()

ax ~ axis
h ~ horizontal,水平的
v ~ vertical,垂直的
span ~ 跨度,区间,范围

这两个函数分别用于设置平行于x轴/y轴的参考区域。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()

# xmin/xmax/ymin/ymax用于设置区间范围
# facecolor用于设置区域颜色
# alpha用于设置透明度
plt.axhspan(ymin=-0.25, ymax=0.25, facecolor='purple', alpha=0.3)
plt.axvspan(xmin=4, xmax=6, facecolor='g', alpha=0.3)

plt.show()
image

8. annotate()

这个函数就是为了在图形中添加指向性注释文本,为了能灵活调整注释的位置以及指示箭头的样式,这个函数提供了丰富的可选参数,想要熟练使用这一函数需要我们花一些功夫去探索。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()

# 这里的参数跟之前几个函数的参数类似,不再赘述
plt.axhspan(ymin=-0.25, ymax=0.25, facecolor='purple', alpha=0.3)
plt.axvspan(xmin=4, xmax=6, facecolor='g', alpha=0.3)

# 使用annotate()添加注释
plt.annotate('maximum',
             xy = (np.pi * 3 / 2, -1),      
             xytext = (np.pi * 3 / 2 - 0.6, -0.7),
             weight = 'bold', 
             color = 'r',
             arrowprops = {
                 'arrowstyle': '->',
                 'connectionstyle': 'arc3',
                 'color': 'r',
                 'alpha': 0.3
             })

plt.show()

可以看到,我们为(π/2, -1)位置的最低点加了一个“minimum”的红色文本注释,这里边我们用到了以下的配置项,它们的含义是:

  • xy: 指示点的坐标,即我们希望注释箭头指向的点的坐标

  • xytext: 注释文本左端的坐标(不是文本中心的坐标)

  • weight: 注释文本的字体粗细风格,bold是粗体,正常粗细则用regular

  • color: 注释文本的颜色

  • arrowprops: arrow + props(properties),箭头属性,字典格式

    • arrowstyle: 箭头类型
    • connectionstyle: 连接类型
    • color: 箭头颜色
  • ...

更多的参数大家可以查阅文档,里边有详细的介绍。至于查阅文档,为大家推荐一个软件,在Mac下有一个叫Dash的软件,简直是文档查阅神器,在Linux和Windows下有一个叫Zeal的替代软件。强烈推荐没用过的同学体验下。

image

9. text()

这个函数同样是用于图形中的注释,但它跟annotate()的区别是它用于添加无指向性注释文本,也就是不带指向性箭头的文本注释。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()

# 这里的参数跟之前几个函数的参数类似,不再赘述
plt.axhspan(ymin=-0.25, ymax=0.25, facecolor='purple', alpha=0.3)
plt.axvspan(xmin=np.pi*3/2-1, xmax=np.pi*3/2+1, facecolor='g', alpha=0.3)

# 使用annotate()添加注释
plt.text(np.pi * 3 / 2 - 0.7, -0.7, 'minimum', weight='regular', color='r', fontsize=12)
plt.text(np.pi * 3 / 2 - 1, 0.7, 'y=sin(x)', weight='regular', color='r', fontsize=16)

plt.show()

由于没有了箭头,我们就不需要那个字典参数了,同时坐标等参数都更直接地使用x、y等来表达。我们使用fontsize参数设置了注释文本的大小。

image

10. title()

这个函数最简单,就是用于设置图形的标题。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()

# 设置标题
plt.title('A Sine Curve')

plt.show()
image

11. legend()

这个函数我们已经见过好多次了,它用于添加图例。

10. title()

这个函数最简单,就是用于设置图形的标题。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')

# 控制图例位置
plt.legend(loc='lower right')

# 设置标题
plt.title('A Sine Curve')

plt.show()

这里我们将图例放在了右下角,图例的位置使用loc参数来控制:

  • upper left: 左上角
  • upper center: 中上
  • upper right: 右上角
  • lower left: 左下角
  • lower center: 中下
  • lower right: 右下角
image

12. 小挑战

在最后,我们用一个小挑战来回顾下之前的内容:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm as cm

# 生成数据
x = np.linspace(0.5, 3.5, 100)
y = np.sin(x)
y1 = np.random.randn(100)

# 创建图形并设置大小
plt.figure(figsize=(12, 8))

# 散点图
plt.scatter(x, y1, c='0.5', label='scatters')

# sin(x)图
plt.plot(x, y, '--g', lw=2, label='sin(x)')

# 样式调整
# 去掉图形上边和右侧的边框
for spine in plt.gca().spines.keys():
    if spine == 'top' or spine == 'right':
        plt.gca().spines[spine].set_color('none')
        
# 设置坐标轴上的刻度线位置(其实这里的设置跟默认一样)
plt.gca().xaxis.set_ticks_position('bottom')
plt.gca().yaxis.set_ticks_position('left')

# 将刻度线放在坐标轴内侧
plt.tick_params(direction = 'in')

# 设置坐标轴范围
plt.xlim(0, 4)
plt.ylim(-3, 3)

# 设置轴标签
plt.xlabel('X 轴')
plt.ylabel('Y 轴')

# 设置网格线
plt.grid(True, ls=':', color='r', alpha=0.5)

# 添加水平参考线
plt.axhline(y=0, c='r', ls='--', lw=2)

# 添加垂直参考区间
plt.axvspan(xmin=1, xmax=2, facecolor='g', alpha=0.1)

# 添加sin(x)的最高点注释
plt.annotate('maximum', 
             xy = (np.pi/2, 1), 
             xytext = (np.pi/2, 1.3), 
             weight = 'regular', 
             color = 'r',
             fontsize = 12,
             arrowprops = {
                 'arrowstyle': '->',
                 'connectionstyle': 'arc3',
                 'color': 'r'
             })

# 添加y轴边框注释
plt.annotate('spines', 
             xy = (0, -2.5), 
             xytext = (0.25, -2.3), 
             weight = 'regular', 
             color = 'c',
             fontsize = 12,
             arrowprops = {
                 'arrowstyle': '->',
                 'connectionstyle': 'arc3',
                 'color': 'c'
             })

# 添加x轴边框注释
plt.annotate('', 
             xy = (0.25, -3), 
             xytext = (0.37, -2.4), 
             arrowprops = {
                 'arrowstyle': '->',
                 'connectionstyle': 'arc3',
                 'color': 'c'
             })

# 添加一个指向tick的箭头
plt.annotate('',
             xy = (3.5, -2.98),
             xytext = (3.6, -2.7),
             arrowprops = {
                 'arrowstyle': '->',
                 'connectionstyle': 'arc3',
                 'color': 'c'
             })

# 在上边的箭头旁添加注释文字
plt.text(3.6, -2.7, "'|' is tickline", weight='bold', color='c')
plt.text(3.6, -2.9, "3.5 is ticklabel", weight='bold', color='c')

# 设置标题
plt.title('Structure of matplotlib')

# 添加图例
plt.legend()

# 展示图形
plt.show()

可以看到,我们配置了很多小细节,是不是很有成就感?

没错,matplotlib就是这么强大,这还仅仅是它的冰山一角呢!

image

好了,以上就是用来作图以及调整图形样式的十来个常用的函数,本文严重参考刘大成先生的《Python数据可视化之matplotlib实践》一书,这本书的组织形式是截止目前我认为讲解matplotlib库中最清晰、最适合新手的,强烈推荐。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容