matplotlib 快速作图

2022/7/6 23:32:23

本文主要是介绍matplotlib 快速作图,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

matplotlib

这是一篇快速画图的简单用法,另一个稍微详细一点的教程,可以见:https://www.cnblogs.com/wztshine/p/15101086.html

简单使用:

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-50, 51)
y = x ** 2

# plt.plot(x, y) 可以根据 x,y 值来绘制图表。
plt.plot(x, y)
plt.title("y=x^2", fontsize=15)  # 添加标题和字体大小

plt.show()  # 显示图表

修改线条样式:

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-50, 51)
y = x ** 2

# +++ linewidth 参数可以设置线条宽度
plt.plot(x, y, linewidth=5)

plt.title("y=x^2", fontsize=15)

plt.show()

支持中文:

matplotlib 默认是不支持中文的,我们需要如下设置让它支持中文。

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-50, 51)
y = x ** 2

plt.plot(x, y)
plt.title("这是标题")

# +++ 多了这两行代码,用来设置字体为黑体;设置坐标轴上负号的编码;之后就能正常显示中文了
plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

坐标轴名称-字体大小

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-50, 51)
y = x ** 2

plt.plot(x, y)
plt.title("这是标题")

# +++ 设置坐标轴名字和字体大小
plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

坐标轴刻度设置:倾斜角度,刻度值,刻度标签,标签颜色

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-50, 51)
y = x ** 2

plt.plot(x, y)
plt.title("这是标题")

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

# +++ 设置坐标轴
plt.xticks(x[::10], labels=['x'+str(i) for i in x[::10]], rotation=30, color="red")

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

plt.xticks(ticks, labels, **kwargs)

  • ticks:你想要设置的刻度列表。上面的例子中,我们将刻度间隔设置成10,这样可以让刻度稀少一点,比较好看。
  • labels:每个刻度上显示的刻度标签文字;默认使用当前刻度的值。如果设置了这个参数,则列表的长度应该和 ticks 一致。
  • kwargs:
    • rotation:设置刻度标签的旋转角度
    • color:刻度标签的颜色

绘制多个线条

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-50, 51)
y = x ** 2

plt.plot(x, y)
plt.title("这是标题")

# +++ 又绘制了一个线条,坐标轴数据可以和之前的线条不一样
plt.plot(x-10, x**3)

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

线条样式

plt.plot(x, y, color='red', alpha=.3, linestyle='-', linewidth=5, marker='o', markeredgecolor='r', markersize=10, markeredgewidth=10)
  • x:x 轴数据
  • y:y 轴数据
  • color:线条颜色,可以是全称如:”red”, 也可以是缩写:’r',也可以是16进制颜色
  • alpha:线条透明度,取值范围 0~1
  • linestyle:
    • - 代表实现
    • -- 代表虚线
    • -. 代表点划线
    • : 代表虚线
  • linewidth:线条宽度
  • marker:线条上数据点的标记类型
    • o 代表圆圈
    • . 代表原点
    • x 代表 x 型
    • D 钻石型标记
    • s 正方形
    • H 六角形
    • + +号
  • markeredgecolor:标记点边缘颜色
  • markersize:标记点大小
  • markeredgewidth:标记点边缘宽度
import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-10, 11)
y = x ** 2

plt.plot(x, y, label="图表1")

# +++ 在绘图时,可以直接指定线条的样式
plt.plot(x-10, x**3, label="图表2", color='red', linestyle='-', linewidth=3, marker='o',
         markeredgecolor='b', markersize=3, markeredgewidth=2)

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

plt.show()

线条样式和数据标记点可以写在一起:

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-10, 11)
y = x ** 2

plt.plot(x, y, label="图表1")

# +++ 在绘图时,可以合并线条和标记点的一些样式
plt.plot(x-10, x**3, 'ro-.')

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

plt.show()

图例

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-50, 51)
y = x ** 2

plt.plot(x, y, label="图表1")
plt.title("这是标题")

# +++ 绘制线条时,给它设置 label
plt.plot(x-10, x**3, label="图表2")
# +++ legend 会自动根据线条的 label,显示图例名称
plt.legend()

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

plt.legend(loc="best") 会自动根据线条的 label 添加图例,并且图例的位置会自动调整。想要自定义图例的位置,loc 参数的可选项有如下:

'best' 0 自适应
'upper right' 1 右上角
'upper left' 2 左上角
'lower left' 3 ..
'lower right' 4 ..
'right' 5
'center left' 6
'center right' 7
'lower center' 8
'upper center' 9
'center' 10

数据点文本

针对线条上的每个数据点,我们可以给它加上文本标记,来显示数据点的值

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-10, 11)
y = x ** 2

plt.plot(x, y, label="图表1")
plt.title("这是标题")

plt.plot(x-10, x**3, label="图表2")
for x, y in list(zip(x-10, x**3)):
    # +++ 意思是:在 (x,y) 坐标点上,添加一个文本:y
    plt.text(x, y, y)
plt.legend()

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

plt.text(x, y, value, horizontalalignment, verticalalignment) 可以在相应的坐标点上添加文字

  • x:x 坐标值
  • y:y 坐标值
  • value:要在 (x, y) 坐标点上添加的文本
  • horizontalalignment:水平对齐方式:['center' | 'top' | 'bottom' | 'baseline']
  • verticalalignment:垂直对齐方式:['center' | 'right' | 'left']

背景网格

plt.grid(True, linestyle='--', color='gray', linewidth=0.5, axis='x', alpha=1)

给坐标轴添加背景网格,可以控制网格的线条,颜色,线条宽度,是横轴的还是纵轴的,以及线条的透明度

  • linestyle:线条样式
  • color:线条颜色
  • linewidth:线条宽度
  • axis:可选为:['x', 'y', 'both'],可以控制 x,y或者两者兼具的网格
  • alpha:控制线条透明度,介于 0~1 之间的数。0 为透明,1为不透明。
import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-10, 11)
y = x ** 2

plt.plot(x, y, label="图表1")
plt.title("这是标题")

plt.plot(x-10, x**3, label="图表2")
for x, y in list(zip(x-10, x**3)):
    plt.text(x, y, y)
plt.legend()

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

# +++ 背景网格
plt.grid(color='gray', axis='both', alpha=0.3)

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

设置坐标轴位置和颜色

坐标轴的四个边框,被称为 spines,它包含了 left, right, top, bottom 四个坐标轴。

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-10, 11)
y = x ** 2

plt.plot(x, y, label="图表1")
plt.title("这是标题")

plt.plot(x-10, x**3, label="图表2")
for x, y in list(zip(x-10, x**3)):
    plt.text(x, y, y)
plt.legend()

plt.xlabel("x 轴", fontsize=16)
plt.ylabel("y 轴")

plt.grid(color='gray', axis='both', alpha=0.3)

# +++ 设置坐标轴
axes = plt.gca()  # 获取坐标轴
axes.spines['right'].set_color("none")  # 设置右侧坐标轴颜色
axes.spines['top'].set_color('none')
axes.spines['left'].set_position(('data', 0))  # 设置坐标轴的位置是 x 轴的0处
axes.spines['bottom'].set_position(('data', 0))  # 设置坐标轴的位置是 y 轴的0处

plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False

plt.show()

set_position() 中有三种不同的设置方式:

  • data: 根据数据值设置位置

  • axes: 根据坐标轴的百分比设置位置。譬如:axes.spines['left'].set_position(('axes', 0.5)) 就是将 y 坐标轴移动到 x 坐标轴 50% 位置处(中点)

  • outward: ...

设置画图分辨率和大小

plt.plot()  # 默认尺寸是 432*288,分辨率72,6*4英寸

plt.rcParams['figure.dpi'] = 100  # 设置分辨率 100,尺寸为 600*400
plt.rcParams['figure.figsize'] = (8, 5)  # 设置英寸大小

图表对象

figure(num=None,     # 编号或名字
       figsize=None, # 图形的长宽,单位英寸
       dpi=None,  # 每英寸的分辨率。默认 72
       facecolor=None,  # 背景色
       edgecolor=None,  # 边框颜色
       frameon=True,    # 是否显示边框
       FigureClass=Figure,
       clear=False,
       **kwargs
      )

譬如:

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(10)
y = x*2

f = plt.figure('f1', figsize=(8, 5), dpi=100, facecolor='gray')
plt.plot(x, y)

plt.show()

多子图

上面说了 Figure ,它是一个图表对象。图表对象可以包含多个 Axes,即坐标轴,每个坐标轴都包含了 Axis 对象,即轴对象。每个坐标轴对象,都可以绘制数据。

figure.add_axes(rect)

这个方法用来生成一个 axes 坐标轴对象,并且我们可以自定义坐标轴在图表中的位置。对象的位置由 rect 决定。rect 是一个位置参数。接受一个由 4 个元素组成的浮点数列表,如:[left, bottom, width, height], 它表示添加到图表中的矩形的左下角坐标,宽度和高度。

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(10)
y = x*2

f = plt.figure('f1', figsize=(8, 5), dpi=100, facecolor='gray')

ax1 = f.add_axes([0.1, 0.1, 0.8, 0.8])  # 添加一个距离图表左侧和底部 10% 间距、宽度和高度均为图表宽高 80% 的坐标轴
ax2 = f.add_axes([0.2, 0.2, 0.5, 0.5])  # 添加一个距离图表左侧和底部 20% 间距、宽度和高度均为图表宽高 50% 的坐标轴

# 坐标轴可以直接 plot 数据。
ax1.plot(x, y)
ax2.plot(x, y)

plt.show()

针对每个坐标轴,我们可以使用 axes.plot 来绘制数据。之前我们都是使用 plt.plot(),其实本质也是通过 plt.gca() 获取当前的 axes ,然后调用 axes.plot() 来绘制数据

plt.subplot()

subplot 可以均匀的划分 figure 区域,来创建多个子图

plt.subplot(nrows, ncols, index, *args, **kwargs)
  • nrows:几行子图
  • ncols:几列子图
  • index:会创建 nrows*ncols 个子图,index 是子图的索引,代表选取第几个子图

上面的 nrows, ncols, index 可以写在一起,譬如:221,代表创建 2 行 2 列共 4 个子图,当前选取第 1 个子图。

import numpy as np
from matplotlib import pyplot as plt

names = ['group_a', 'group_b', 'group_c']
values = [1, 10, 100]

plt.figure(figsize=(9, 3))

plt.subplot(121)        # 创建1行2列共2个图,当前是在第一个子图上
plt.bar(names, values)  # 在这第一个子图上画一个柱状图

plt.subplot(122)        # 切换到第二个子图
plt.scatter(names, values)  # 第二个上画散点图

plt.show()

创建合并的子图,即一个子图横跨多列或者多行:

import matplotlib.pyplot as plt


plt.subplot(121)  # 1列2行第1个
plt.subplot(222)  # 2列2行第2个
plt.subplot(224)  # 2列2行第4个

plt.show()

figure.add_subplot

上面是使用 plt.subplot ,其实它的本质是先通过 plt.gcf() 来获取当前 figure 对象,然后调用 fig.add_subplot() 实现的

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

ax2 = fig.add_subplot(122)

plt.show()

异形的子图,譬如你想让某个子图横跨或者纵跨几个子图,可以这样做:

import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,(3,4)) # 第三个 Axes 横跨 3和4 这两个子图,所以占据两个位置,相当于Excel合并单元格
plt.show()

subplots

subplot 类似,但是 subplot 返回的是一个 Axes 对象。而 subplots 返回 Figure 对象以及 Figure 中的多个 Axes 对象。

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(2, 2)

axes[0][1].plot(np.arange(5))  # 对第一行的第二个图绘制数据
axes[1][1].plot(np.arange(10)) # 对第二行的第二个图绘制数据

plt.show()

上面的 axes 是一个 numpy.ndarray 对象,里面包含了多个子图。

柱状图

plt.bar(x, height, width=0.8, bottom=None, * align='center', data=None, alpha=1, edgecolor, linewidth=None, tick_label, facecolor, linestyle)

x:x轴上的值

height:y轴值

width:柱子的宽度

bottom:柱子的底部数据。默认是放在 x 轴上。如果你想画堆叠的柱状图,可以将一个柱子的底部放在另一个柱子的顶部,这样就堆叠起来了。

align:柱子对齐方式,居中对齐x轴刻度。

alpah:柱子透明度

edgecolor:柱子边缘颜色

linewidth:柱子边缘宽度

facecolor:柱子的填充颜色

tick_label:柱子的数据标签

基本柱状图

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1,2,3])
y = x * 2

plt.title("Bar")
plt.bar(x, y, facecolor='red')

plt.show()

同位置多柱状图

在同一个横坐标位置画多个柱状图,柱子之间会有重叠和遮盖,因此我们需要手动将柱子错开。

import matplotlib.pyplot as plt
import numpy as np

x = ["English", "Math"]
y1 = [100, 90]
y2 = [80, 130]

bar_width = 0.2  # 柱子宽度
x_1 = np.arange(len(x))  # 将字符串型的横坐标,转换成数字,用来给 y1 设置的横坐标
x_2 = x_1 + bar_width  # 右移一个柱子的宽度,给 y2 设置的横坐标

# 分别在 x1, x2 的横坐标上画柱状图,这样它们就并排显示了
plt.bar(x_1, y1, width=bar_width)
plt.bar(x_2, y2, width=bar_width)

# 最后将横坐标刻度的位置移动到两个柱子中心点,然后使用原先的横坐标字符串来给坐标设置 label
plt.xticks(x_1 + bar_width/2, labels=x)

plt.show()

堆叠柱状图

import matplotlib.pyplot as plt
import numpy as np


x = [1,2,3,4,5]
h = [1,2,3,4,5]
c = ['r','b','g','grey','y']

fig, ax = plt.subplots()
ax.bar(x, h,color=c,tick_label=x) # 第一组数据,默认以0为底部起点
ax.bar(x,h,bottom=h,color=c[::-1]) # 第二组数据,以第一组数据值的高度为起点,这样就叠加起了两组数据

plt.show()

水平柱状图

import matplotlib.pyplot as plt
import numpy as np


y = [1,2,3,4,5]
h = [10,2,3,4,5]
c = ['r','b','g','grey','y']

fig, ax = plt.subplots()
ax.barh(y, h,color=c,tick_label=y) # 默认以0为底部起点

plt.show()

水平堆叠柱状图

import matplotlib.pyplot as plt
import numpy as np


y = [1,2,3,4,5]
h = [10,2,3,4,5]
c = ['r','b','g','grey','y']

fig, ax = plt.subplots()
ax.barh(y, h,color=c,tick_label=y) # 默认不写 left 参数,以 0 为底部起点
ax.barh(y, h, left=h)  # left 设置左侧起始位置为 h

plt.show()

水平同位置多柱状图

import matplotlib.pyplot as plt
import numpy as np


y = np.array([1,2,3,4,5])
h = [10,2,3,4,5]
width = 0.4

fig, ax = plt.subplots()
ax.barh(y, h, height=width)  # 柱子的宽度参数叫做 height
ax.barh(y+width, h, height=width)  # 将刻度值上移一个宽度

ax.set_yticks(y+width/2, y)  # 将刻度移动到两个柱子中间,并将刻度标签设成原数值

plt.show()

直方图

直方图和柱状图很像。它们的区别是,直方图的横坐标是一个区间,而柱状图的横坐标是某一系列的数据。

plt.hist(x, bins=None, range=None, density=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, *, data=None, **kwargs)
  • x:绘制的数据,必须是一维数组,多维数组要展开
  • bins:如果是整数,则代表了等距的柱子的个数,默认是10。如果参数是一个序列,则代表了柱子们横坐标的起始值,譬如:[1,2,3,4] 代表第一个柱子的区间是:[1, 2), 第二个柱子区间是:[2, 3), 第三个是 [3, 4]
  • weights:每个柱子的权重
  • density:布尔值;
import matplotlib.pyplot as plt
import numpy as np

x = np.random.randint(10, 100, 50)

plt.hist(x, bins=10, edgecolor='white')  # 设置 10根柱子,柱子边缘色为白色

plt.show()

直方图的返回值

n, bins, pathes = plt.hist(...)

n:一个列表,里面是每根柱子的 y 轴的值。

bins:一个列表,里面是每根柱子的 x 轴的起点值和最后一根柱子的结尾值,因此这个列表的长度会比柱子的个数多一个

pathes:可迭代的对象,里面包含了所有的柱子对象。可以通过 obj.get_x(), obj.get_y(), obj.get_width() 等来获取柱子的属性。

不等距直方图

import matplotlib.pyplot as plt
import numpy as np

x = [1,23,23,10,29]

plt.hist(x, bins=[1,10, 30], edgecolor='white')  # bins 控制间距

plt.show()

堆叠直方图

import matplotlib.pyplot as plt
import numpy as np

x = [1,23,23,10,29]
y = [11, 2, 25, 46]

plt.hist([x, y], bins=[1,10, 30], edgecolor='white', stacked=True, label=['A', 'B'])  # stabked 可以堆叠
plt.legend()
plt.show()

饼状图

import matplotlib.pyplot as plt
import numpy as np

x = [500, 100, 200, 400]
labels = ['A', 'B', 'C', 'D']
explode = [0, 0.03, 0.03, 0.5]  # 这些数是用来控制每个饼图区域离圆心的距离,即让各个饼图之间打散一些。不加距离,则是一个完全闭合的圆。

plt.pie(x, labels=labels, autopct='%.2f%%', explode=explode)

plt.show()

plt.pie 可以绘制饼图。autopct 参数用来给饼图区域添加所占百分比数。explode 设置各区域离圆心的距离

还有两个参数:pctdistance, labeldistance 用来控制百分比的数字距离圆心的距离,和标签距离圆心的距离。参数的类型都是浮点数。

散点图

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randint(10, 100, 20)
y = np.random.randint(10, 50, 20)
s = np.random.randint(20, 300, 20)

# x, y 是点的坐标。s 是每个点的面积大小。散点图可以绘制不同大小的点
plt.scatter(x, y, s)

plt.show()

散点颜色

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randint(10, 100, 20)
y = np.random.randint(10, 50, 20)
s = np.random.randint(20, 300, 20)

c = np.random.rand(20)  # 生成一组随机数,可以被用来当作颜色
plt.scatter(x, y, s, c=c)

plt.show()

cmap

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randint(10, 100, 20)
y = np.random.randint(10, 50, 20)
s = np.random.randint(20, 300, 20)

c = np.random.rand(20)
plt.scatter(x, y, s, c=c, cmap="Blues")  # 当颜色使用了浮点数时,可以使用 cmap 参数来指定一些渐变的色系,让散点的颜色分布在这个色系中

plt.show()

箱体图

在箱体图中,用上四分位数到下四分位数绘制一个箱子,然后用触须穿过盒子,上垂线延伸至上边缘(最大值),下垂线延伸至最小值。有时会有数据超出上下边缘,这种数据是异常值。

boxplot(
        x, notch=None, sym=None, vert=None, whis=None,
        positions=None, widths=None, patch_artist=None,
        bootstrap=None, usermedians=None, conf_intervals=None,
        meanline=None, showmeans=None, showcaps=None, showbox=None,
        showfliers=None, boxprops=None, labels=None, flierprops=None,
        medianprops=None, meanprops=None, capprops=None,
        whiskerprops=None, manage_ticks=True, autorange=False,
        zorder=None, *, data=None)

x:绘制的数据

vert:箱体的方向。True 时为垂直方向,False 为水平方向。

showmeans:为 True 时显示算术平均值。

meanline:为 True 时,算术平均值显示为线条的样式。

import matplotlib.pyplot as plt
import numpy as np

x = np.random.rand(20)

plt.boxplot(x, showmeans=True, meanline=True)  # 显示平均值,并将平均值显示成线条的样式

plt.show()

箱体图可以处理多维数据,它会将每列数据,绘制成一个箱子

import matplotlib.pyplot as plt
import numpy as np

x = np.random.rand(20).reshape(4,5)  # 多维数据

plt.boxplot(x, showmeans=True, meanline=True, labels="ABCDE")

plt.show()

保存图片

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randint(10, 100, 20)
y = np.random.randint(10, 50, 20)
s = np.random.randint(20, 300, 20)
c = np.random.rand(20)
plt.scatter(x, y, s, c=c, cmap="Blues")

plt.savefig('my_img.jpg', dpi=300) 


这篇关于matplotlib 快速作图的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程