Matplotlib基础--个性化颜色条

摘要:
Matplotlib的颜色条是一个类似于独立于图表的颜色比较图表的图形,用于显示图表中不同颜色的数字含义。Matplotlib的在线文档中也有一个关于彩色地图选择的有趣章节。Jet颜色映射是Matplotlib 2.0之前的默认颜色映射。它是定性颜色映射的一个示例。一个更好的选择是使用像viridis这样的彩色地图,它们被设计为具有均匀的亮度变化。Matplotlib有大量可用的颜色贴图;要查看它们的列表,可以使用IPython来探索plt。cm模块。颜色限制和扩展Matplotlib允许您自定义颜色栏。

图例可以将离散的点标示为离散的标签。对于建立在不同颜色之上的连续的值(点线面)来说,标注了的颜色条是非常方便的工具。Matplotlib 的颜色条是独立于图表之外的一个类似于比色卡的图形,用来展示图表中不同颜色的数值含义。本节内容中的所有带色彩的图都可以在(https://github.com/wangyingsm/Python-Data-Science-Handbook)中找到。我们还是首先导入本节需要的包和模块:

import matplotlib.pyplot as plt
plt.style.use('classic')
import numpy as np

通过plt.colorbar函数可以创建最简单的颜色条,在本节中我们会多次看到:

x = np.linspace(0, 10, 1000)
I = np.sin(x) * np.cos(x[:, np.newaxis])

plt.imshow(I)
plt.colorbar();
plt.show()
 

Matplotlib基础--个性化颜色条第1张

我们下面来讨论如何个性化颜色条以及在不同的场合高效的使用它们。

自定义颜色条

颜色条可以通过cmap参数指定使用的色谱系统(或叫色图):

plt.imshow(I, cmap='gray');

Matplotlib基础--个性化颜色条第2张

 所有可用的色图都可以在plt.cm模块中找到;在 IPython 中使用 Tab 自动补全功能能列出所有的色图列表:

plt.cm.<TAB>

但是知道在哪里选择色图只是第一步:更重要的是在各种选项中选出合适的色图。这个选择比你预料的要微妙的多。

选择色图

在可视化方案中选择颜色完整的介绍说明超出了本书的范围,如果你对这个课题和相关内容有兴趣,可以参考文章["绘制更漂亮图表的 10 个简单规则"](http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1003833)。Matplotlib 的在线文档也有一章关于色图选择的有趣讨论。

通常来说,你应该注意以下三种不同类型的色图:

  • 序列色图:这类型的色谱只包括一个连续序列的色系(例如binaryviridis)。
  • 分化色图:这类型的色谱包括两种独立的色系,这两种颜色有着非常大的对比度(例如RdBuPuOr)。
  • 定性色图:这类型的色图混合了非特定连续序列的颜色(例如rainbowjet)。

jet色图,在 Matplotlib 2.0 版本之前都是默认的色图,是定性色图的一个例子。jet作为默认色图的位置其实有点尴尬,因为定性图通常都不是对定量数据进行展示的好选择。原因是定性图通常都不能在范围增加时提供亮度的均匀增长。

我们可以通过将jet颜色条转换为黑白来看到这点:

from matplotlib.colors import LinearSegmentedColormap

def grayscale_cmap(cmap):
    """返回给定色图的灰度版本"""
    cmap = plt.cm.get_cmap(cmap) # 使用名称获取色图对象
    colors = cmap(np.arange(cmap.N)) # 将色图对象转为RGBA矩阵,形状为N×4

    # 将RGBA颜色转换为灰度
    # 参考 http://alienryderflex.com/hsp.html
    RGB_weight = [0.299, 0.587, 0.114] # RGB三色的权重值
    luminance = np.sqrt(np.dot(colors[:, :3] ** 2, RGB_weight)) # RGB平方值和权重的点积开平方根
    colors[:, :3] = luminance[:, np.newaxis] # 得到灰度值矩阵
    # 返回相应的灰度值色图
    return LinearSegmentedColormap.from_list(cmap.name + "_gray", colors, cmap.N)


def view_colormap(cmap):
    """将色图对应的灰度版本绘制出来"""
    cmap = plt.cm.get_cmap(cmap)
    colors = cmap(np.arange(cmap.N))

    cmap = grayscale_cmap(cmap)
    grayscale = cmap(np.arange(cmap.N))

    fig, ax = plt.subplots(2, figsize=(6, 2),
                           subplot_kw=dict(xticks=[], yticks=[]))
    ax[0].imshow([colors], extent=[0, 10, 0, 1])
    ax[1].imshow([grayscale], extent=[0, 10, 0, 1])
view_colormap('jet')

Matplotlib基础--个性化颜色条第3张

 注意一下上面的灰度图中亮条纹的位置。即使在上述彩色图中,也出现了这种不规则的亮条纹,这会导致眼睛被区域中亮条纹所吸引,这很可能造成阅读者被不重要的数据集部分干扰了。更好的选择是使用类似viridis这样的色图(Matplotlib 2.0 后默认色图),它们被设计为有着均匀的亮度变化。因此它们无论是在彩色图中还是在灰度图中都有着同样的亮度变化:

view_colormap('viridis')

Matplotlib基础--个性化颜色条第4张

 如果你更喜欢彩虹方案,另一个好的选择是使用cubehelix色图:

view_colormap('cubehelix')

Matplotlib基础--个性化颜色条第5张

 对于其他的情况,例如某种正负分布的数据集,双色颜色条如RdBu(Red-Blue)会很常用。然而正如你从下面例子看到的,如果将双色颜色条转化为灰度的话,正负或两级的信息就会丢失:

view_colormap('RdBu')

Matplotlib基础--个性化颜色条第6张

后面我们会看到更多使用这些色图的例子。

Matplotlib 中有大量可用的色图;要看到它们的列表,你可以使用 IPython 来探索plt.cm模块。要在 Python 中更加正规的使用颜色,你可以查看 Seaborn 库的工具和文档

颜色限制和扩展

Matplotlib 允许你对颜色条进行大量的自定义。颜色条本身就是一个plt.Axes对象,因此所有轴和刻度定制的技巧都可以应用在上面。颜色条也有着一些有趣的自定义行为:例如,我们可以缩小颜色的范围并且通过设置extend参数将超出范围之外的数值展示为顶部和底部的三角箭头形状。这对于展示一些受到噪声干扰的数据时非常方便:

x = np.linspace(0, 10, 1000)
I = np.sin(x) * np.cos(x[:, np.newaxis])
# 在I数组中人为生成不超过1%的噪声
speckles = (np.random.random(I.shape) < 0.01)
I[speckles] = np.random.normal(0, 3, np.count_nonzero(speckles))

plt.figure(figsize=(10, 3.5))
# 不考虑去除噪声时的颜色分布
plt.subplot(1, 2, 1)
plt.imshow(I, cmap='RdBu')
plt.colorbar()
# 设置去除噪声时的颜色分布
plt.subplot(1, 2, 2)
plt.imshow(I, cmap='RdBu')
plt.colorbar(extend='both')
plt.clim(-1, 1);
plt.show()

Matplotlib基础--个性化颜色条第7张 

注意到在左边的图表中,默认的颜色阈值是包括了噪声的,因此整体的条纹形状都被噪声数据冲刷淡化了。而右边的图表,我们手动设置了颜色的阈值,并在绘制颜色条是加上了extend参数来表示超出阈值的数据。对于我们的数据来说,右图比左图要好的多。

离散颜色条

色图默认是连续的,但是在某些情况下你可能需要展示离散值。最简单的方法是使plt.cm.get_cmap()函数,在传递某个色图名称的同时,还额外传递一个颜色分桶的数量值参数给该函数:

plt.imshow(I, cmap=plt.cm.get_cmap('Blues', 6))
plt.colorbar()
plt.clim(-1, 1);

Matplotlib基础--个性化颜色条第8张

离散色图的使用方式和其他色图没有任何区别。

例子:手写数字

最后我们来看一个很有实用价值的例子,让我们实现对一些手写数字图像数据的可视化分析。这个数据包含在 Sciki-Learn 中,以供包含有将近 2,000 张8*8 大小的不同笔迹的手写数字缩略图。

首先,我们下载这个数据集,然后使用plt.imshow()将其中部分数据展示出来:

# 读取数字0-5的手写图像,然后使用Matplotlib展示头64张缩略图
from sklearn.datasets import load_digits
digits = load_digits(n_class=6)

fig, ax = plt.subplots(8, 8, figsize=(6, 6))
for i, axi in enumerate(ax.flat):
    axi.imshow(digits.images[i], cmap='binary')
    axi.set(xticks=[], yticks=[])
plt.show()

Matplotlib基础--个性化颜色条第9张

因为每个数字都是使用 64 个像素点渲染出来的,我们可以认为每个数字是一个 64 维空间中的点:每个维度代表这其中一个像素的灰度值。但是要在图表中将这么高维度空间的联系可视化出来是非常困难的。有一种做法是使用降维技术,比方说使用流形学习来减少数据的维度然而不会丢失数据中有效的信息。

我们来看一下将这些手写数字图像数据映射到二维流形学习当中:

# 使用Isomap将手写数字图像映射到二维流形学习中
from sklearn.manifold import Isomap
iso = Isomap(n_components=2)
projection = iso.fit_transform(digits.data)

我们使用离散颜色条来展示结果,设置ticksclim来进一步美化结果的颜色条:

# 绘制图表结果
plt.scatter(projection[:, 0], projection[:, 1], lw=0.1,
            c=digits.target, cmap=plt.cm.get_cmap('cubehelix', 6))
plt.colorbar(ticks=range(6), label='digit value')
plt.clim(-0.5, 5.5)
plt.show()

Matplotlib基础--个性化颜色条第10张

 我们从流形学习中的映射中可以观察到一些有趣现象:例如,图表中 5 和 3 有一些重叠的部分,这表示一些手写体中 5 和 3 是比较难以辨别的,因此对于自动识别算法来说这是比较容易混淆的部分。而 0 和 1,它们在图表中距离很远,这表示两者比较容易辨别,不太可能造成混淆。这个图表分析与我们的直觉一致,因为 5 和 3 显然比 0 和 1 看起来更加接近。

免责声明:文章转载自《Matplotlib基础--个性化颜色条》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇从串口登录Linux主机android 适配器simpleadapter和baseadapter区别下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

matplotlib的学习16-animation动画

from matplotlib import pyplot as plt from matplotlib import animation import numpy as np fig, ax = plt.subplots() x = np.arange(0, 2*np.pi, 0.01) line, = ax.plot(x, np.sin(x)) #...

&amp;lt;QT&amp;gt;将matplotlib图形嵌入到PySide2界面中

https://blog.csdn.net/weixin_43469047/article/details/115607083 https://blog.csdn.net/qq_28053421/article/details/113828372 https://blog.csdn.net/weixin_43469047/article/details/1...

python的2D绘图库matplotlib

matplotlib的官方文档https://matplotlib.org/api/,以下介绍基本操作。 1、指定画布 画布的像素大小为指定画布的尺寸figsize及每尺寸表达的像素点数dpi的乘积。 plt.figure(figsize=(5,5),dpi=100)#figsize指定画布的大小(单位为英寸),dpi指定每英寸点(像素点)的个数 可参看官...

使用 matplotlib 绘制条形码

使用 matplotlib 绘制条形码 源码及参考链接 效果图 代码 import numpy as np import matplotlib.pyplot as plt code = np.array([ 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1,...

Matplotlib 绘图

Matplotlib 提供非常全面的数据可视化功能。 安装 非常简单,直接 执行 pip install matplotlib 即可 简单示例 下面的代码,运行一下看看 import matplotlib.pyplot as plt # 如果只传入一个数组作为参数, matplotlib 认为是 Y 轴的坐标 # 并自动产生 从 0 开始的 对应 X 轴...

ROS入门笔记(五):ROS中运行rqt_plot的问题(kinetic)

ROS入门笔记(五):ROS中运行rqt_plot的问题(kinetic) rqt_plot的问题(kinetic)    1.1 问题    1.2 原因    1.3 解决方法    1.4 deb文件怎么安装? rqt_plot的问题(kinetic) 1.1 问题 运行:rqt_plot rosrun rqt_plot rqt_plot gg...