基于Python的数据科学(8):Matplotlib基础

简介

        Matplotlib 是一个基于 NumPy 数组的数据可视化库。它由 John Hunter 于 2002 年构思,最初作为 IPython 的补丁,通过 gnuplot 从 IPython 命令行启用交互式 MATLAB 风格的绘图。Matplotlib 最重要的特性之一是它可以与许多操作系统和图形后端良好配合。Matplotlib 支持数十种后端和输出类型,这意味着无论使用哪种操作系统或输出格式,都可以指望它正常工作。

        最近的 Matplotlib 版本使得设置新的全局绘图样式相对容易,而且人们已经开发了新的包,这些包建立在其强大的内部结构上,通过更简洁、更现代的 API 驱动 Matplotlib,例如 Seaborn、ggpy、HoloViews、Altair,甚至 Pandas 本身也可以作为 Matplotlib API 的封装器。即使使用这些封装器,有时深入研究 Matplotlib 的语法以调整最终的绘图输出仍然是有用的。

导入 Matplotlib

import matplotlib as mpl
import matplotlib.pyplot as plt

设置样式

# 列出所有可用的样式
plt.style.available

# 使用 seaborn-whitegrid 样式
plt.style.use('seaborn-whitegrid')

简单线条绘图

        使用面向对象(OO)风格:

import numpy as np

fig = plt.figure()
ax = plt.axes()  # 获取 axes 的实例

x = np.linspace(0, 10, 1000)
ax.plot(x, np.sin(x))  # 绘制 x, y 轴
ax.plot(x, np.cos(x))

        使用 MATLAB 风格:

plt.plot(x, np.sin(x))  # 绘制 x, y 轴
plt.plot(x, np.cos(x))

# 多种颜色选项
plt.plot(x, np.sin(x - 0), color='blue')        # 指定颜色名称
plt.plot(x, np.sin(x - 1), color='g')           # 短颜色代码(rgbcmyk)
plt.plot(x, np.sin(x - 2), color='0.75')        # 0 到 1 之间的灰度
plt.plot(x, np.sin(x - 3), color='#FFDD44')     # 十六进制代码(RRGGBB,从00到FF)
plt.plot(x, np.sin(x - 4), color=(1.0,0.2,0.3)) # RGB 元组,值为 0 到 1
plt.plot(x, np.sin(x - 5), color='chartreuse'); # 所有 HTML 颜色名称均受支持

散点图

        使用 plt.plot 不同形状的标记来创建散点图:

x = np.linspace(0, 10, 30)
y = np.sin(x)

plt.plot(x, y, 'o', color='black');

错误条

        使用 plt.errorbar:

x = np.linspace(0, 10, 50)
dy = 0.8
y = np.sin(x) + dy * np.random.randn(50)

plt.errorbar(x, y, yerr=dy, fmt='ok', ecolor='lightgray', elinewidth=3, capsize=5)

直方图

        简单的直方图是理解数据集的一个很好的第一步:

data = np.random.normal(0, 1, 1000)  # 0 和 1 之间的 1000 个数字
plt.hist(data, bins=30, alpha=0.5)

多个子图

        使用 plt.subplot(s) 创建多个子图:

fig, ax = plt.subplots(2, 3, sharex='col', sharey='row')
ax[0, 0].plot(x, y)  # 行列
ax[0, 1].plot(x, y)
ax[1, 2].plot(x, y)

任务 1

# 任务 1

# 生成数据 y = 2x - 5 + 20 * noise,其中 noise 是 0 和 10 之间的值,生成 500 个 0 和 1 之间的 x 值,并生成相应的 y 值。
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 1, 500)
noise = np.random.uniform(0, 10, 500)
y = 2 * x - 5 + 20 * noise

# 使用散点图绘制上述数据
plt.scatter(x, y, label='Data Points')

# 在散点图上绘制一条线 y = 2x - 5
y_line = 2 * x - 5
plt.plot(x, y_line, color='red', label='y = 2x - 5')
plt.legend()
plt.show()

# 给定一个 sigmoid 函数 y = 1 / (1 + np.exp(-x)),生成从 -5 到 5 的 x 值,然后生成相应的 y 值。绘制散点图,设置标题为 “Sigmoid 函数”,xlabel 为 “x”,ylabel 为 “y”。
x_sigmoid = np.linspace(-5, 5, 500)
y_sigmoid = 1 / (1 + np.exp(-x_sigmoid))

plt.scatter(x_sigmoid, y_sigmoid)
plt.title("Sigmoid 函数")
plt.xlabel("x")
plt.ylabel("y")
plt.show()

# 使用 sklearn.datasets 的 make_classification API 生成 500 个样本,n_features=10。然后绘制前两个特征的散点图,颜色等于其类,标记为 'o',大小为 25,边框颜色为黑色。
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=500, n_features=10, n_informative=2, n_redundant=0, n_clusters_per_class=1)
plt.scatter(X[:, 0], X[:, 1], c=y, marker='o', s=25, edgecolor='black')
plt.show()

# 从 sklearn 加载 iris 数据集,将前两个特征设置为 X,将目标设置为 y。用颜色表示它们的类绘制散点图。为图添加网格。
from sklearn.datasets import load_iris

iris = load_iris()
X = iris.data[:, :2]
y = iris.target

plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1, edgecolor='k')
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.grid(True)
plt.show()

# 重新构建如下图所示的图表
x_neg = np.array([[3,4],[1,4],[2,3]])
y_neg = np.array([-1,-1,-1])
x_pos = np.array([[6,-1],[7,-1],[5,-3],[2,4]])
y_pos = np.array([1,1,1,1])
x1 = np.linspace(-10, 10)

plt.scatter(x_neg[:, 0], x_neg[:, 1], color='red', label='Negative')
plt.scatter(x_pos[:, 0], x_pos[:, 1], color='blue', label='Positive')
plt.legend()
plt.show()

# 绘制四个大圆圈
from sklearn.datasets import make_blobs

X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
plt.scatter(X[:, 0], X[:, 1], s=50)

centers = np.array([[1, 1], [-1, -1], [1, -1], [-1, 1]])
plt.scatter(centers[:, 0], centers[:, 1], c='black', s=200, alpha=0.5)
plt.show()

3D绘图

        我们可以通过导入mplot3d库来启用3D绘图,该库随标准的Matplotlib安装一起提供。只需确保您的Matplotlib版本高于1.0。一旦导入了这个子模块,就可以通过将关键字projection="3d"传递给任何常规的Matplotlib轴创建函数来创建3D图。

from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax  = plt.axes(projection="3d")

plt.show()

        这些3D绘图函数非常直观:我们可以用scatter3D替代scatter,并传递x、y和z数据。所有其他函数设置,如颜色和线型,与2D绘图函数相同。

3D散点图和线图
fig = plt.figure()
ax  = plt.axes(projection="3d")

z_line = np.linspace(0, 15, 1000)
x_line = np.cos(z_line)
y_line = np.sin(z_line)
ax.plot3D(x_line, y_line, z_line, 'gray')

z_points = 15 * np.random.random(100)
x_points = np.cos(z_points) + 0.1 * np.random.randn(100)
y_points = np.sin(z_points) + 0.1 * np.random.randn(100)
ax.scatter3D(x_points, y_points, z_points, c=z_points, cmap='hsv')

plt.show()

曲面图

        曲面图可以很好地可视化三个变量之间的关系。它们展示了每个变量如何在另外两个变量的轴上变化的整体结构和视图。构建曲面图在Matplotlib中是一个三步过程。

        首先,我们需要生成组成曲面图的实际点。生成所有3D表面的点是不可能的,因为它们是无限多的!因此,我们只生成足够的点来估计表面,然后推断其余的点。我们将定义x和y点,然后使用函数计算z点。

fig = plt.figure()
ax  = plt.axes(projection="3d")
def z_function(x, y):
    return np.sin(np.sqrt(x ** 2 + y ** 2))

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

X, Y = np.meshgrid(x, y)
Z    = z_function(X, Y)

        第二步是绘制线框图——这是我们对表面的估计。

fig = plt.figure()
ax  = plt.axes(projection="3d")
ax.plot_wireframe(X, Y, Z, color='green')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

plt.show()

        最后,我们将在线框图上投影我们的表面并推断所有点。

ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='winter', edgecolor='none')
ax.set_title('surface')
3D柱状图

        我们将选择z轴来编码每个柱状图的高度;因此,每个柱状图将从z=0开始,并具有与我们要可视化的值成比例的大小。x和y位置将表示z=0的2D平面上的柱状图坐标。我们将每个柱状图的x和y大小设置为1,以便所有柱状图具有相同的形状。

import random

fig = plt.figure()
ax  = plt.axes(projection="3d")

num_bars = 15
x_pos  = random.sample(list(range(20)), num_bars)
y_pos  = random.sample(list(range(20)), num_bars)
z_pos  = [0] * num_bars
x_size = np.ones(num_bars)
y_size = np.ones(num_bars)
z_size = random.sample(list(range(20)), num_bars)

ax.bar3d(x_pos, y_pos, z_pos, x_size, y_size, z_size, color='aqua')
plt.show()

日期刻度标签

        您可以使用set_major_locatorset_major_formatterset_minor_locator来格式化刻度。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

plt.rcParams.update({'xtick.labelsize': 10, 'xtick.major.size': 10, 'xtick.minor.size': 5})

years     = mdates.YearLocator()   # 每年
months    = mdates.MonthLocator()  # 每月
years_fmt = mdates.DateFormatter('%Y')

from pandas_datareader import data

goog = data.DataReader('GOOG', start='2004', end='2016', data_source='yahoo')
goog = goog['Adj Close']

fig, ax = plt.subplots(figsize=(10, 10))
ax.plot(goog)

# 格式化刻度
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(years_fmt)
ax.xaxis.set_minor_locator(months)

# 格式化坐标消息框
ax.format_xdata = mdates.DateFormatter('%Y-%m-%d')
ax.format_ydata = lambda x: '$%1.2f' % x  # 格式化价格
ax.grid(True)

# 旋转和右对齐x标签,并将轴底部向上移动以腾出空间
fig.autofmt_xdate()

plt.show()

表格

        我们可以使用.table在图中嵌入一些表格信息。

import numpy as np
import matplotlib.pyplot as plt

data = [[ 66386, 174296,  75131, 577908,  32015],
        [ 58230, 381139,  78045,  99308, 160454],
        [ 89135,  80552, 152558, 497981, 603535],
        [ 78415,  81858, 150656, 193263,  69638],
        [139361, 331509, 343164, 781380,  52269]]

columns = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail')
rows    = ['%d year' % x for x in (100, 50, 20, 10, 5)]

values = np.arange(0, 2500, 500)
value_increment = 1000

# 获取一些淡色
colors = plt.cm.BuPu(np.linspace(0, 0.5, len(rows)))
n_rows = len(data)

# 条形图的位置
index = np.arange(len(columns)) + 0.3
bar_width = 0.4

# 初始化堆叠条形图的垂直偏移
y_offset = np.zeros(len(columns))

print(y_offset)

# 绘制条形图并为表格创建文本标签
cell_text = []
for row in range(n_rows):
    plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row])
    y_offset = y_offset + data[row]
    print(['%1.1f' % (x / 1000.0) for x in y_offset])
    cell_text.append(['%1.1f' % (x / 1000.0) for x in y_offset])
# 反转颜色和文本标签以在顶部显示最后一个值
colors = colors[::-1]
cell_text.reverse()

# 在轴的底部添加表格
the_table = plt.table(cellText=cell_text,
                      rowLabels=rows,
                      rowColours=colors,
                      colLabels=columns,
                      loc='bottom')

# 调整布局以腾出空间
plt.subplots_adjust(left=0.2, bottom=0.2)

plt.ylabel("损失金额 (${0})".format(value_increment))
plt.yticks(values * value_increment, ['%d' % val for val in values])
plt.xticks([])
plt.title('灾害损失')

plt.show()

任务 2

  1. 加载鸢尾花数据,将前两列设为X,将目标设为y
  2. 导入支持向量机(SVM)分类算法
  3. 使用线性核拟合SVM模型
  4. 找到每个特征值的最小值和最大值
  5. 生成所有可能的x和y值
  6. 打印生成的xx和yy。思考这些值与x和y的关系,以及0.2的作用
  7. 创建Z值
  8. 研究ravel()和predict()的作用
  9. 绘制决策边界等高线图
  10. 思考为什么要将Z重塑为xx的形状?cmap是什么?
  11. 绘制训练点,设置图形的x轴和y轴范围,设置标签,并显示图形
 
# 任务2代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import load_iris

# 1. 加载鸢尾花数据,将前两列设为X,将目标设为y
iris = load_iris()
X = iris.data[:, :2]  # 只取前两个特征
y = iris.target

# 2. 导入支持向量机(SVM)分类算法
# 3. 使用线性核拟合SVM模型
model = svm.SVC(kernel='linear').fit(X, y)

# 4. 找到每个特征值的最小值和最大值
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

# 5. 生成所有可能的x和y值
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.2), np.arange(y_min, y_max, 0.2))

# 6. 打印xx和yy
print(xx)
print(yy)

# 7. 创建Z值
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])

# 8. 研究ravel()和predict()的作用
# ravel()将多维数组展平成一维数组
# predict()用于预测给定输入数据的标签

# 9. 重塑Z值
Z = Z.reshape(xx.shape)

# 绘制决策边界等高线图
plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)

# 11. 绘制训练点
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.coolwarm, edgecolors='k')

# 设置图形的x轴和y轴范围
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())

# 设置标签
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.title("SVM Decision Boundary with Iris Data")

# 显示图形
plt.show()

结语

        在本篇文章中,我们深入探讨了Matplotlib库在数据可视化中的广泛应用。从简单的线条绘图、散点图到复杂的3D图形和表格,我们了解了如何利用Matplotlib强大的功能来创建各种类型的图表。此外,我们还学习了如何通过设置样式、美化图表以及在图表中添加注释和表格来增强图表的表现力。掌握这些技能将帮助我们更好地展示和分析数据,为我们的数据科学工作增添更多的可能性。希望通过本篇的学习,您能更自信地运用Matplotlib进行数据可视化,提升数据分析的效果和表达力。

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的Anthony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值