matplotlib的demo演示讲解,matplotlib实现渐变亢保星
#!/usr/bin/env python #-*- coding:utf-8 -*- """ Matplotlib does not natively support gradients. Matplotlib 本身并不支持渐变。 However, we can emulate a gradient-filled rectangle by an AxesImage of the right size and coloring. 然而 我们可以通过正好大小和颜色的AxesImage对象模拟渐变的正方形 In particular, we use a colormap to generate the actual colors. 特别的,我们可以使用colormap来生成实际的颜色 It is then sufficient to define the underlying values on the corners of the image and let bicubic interpolation fill out the area. 先定义图片角落的基础值,然后利用双三次的算法来对图片的其它区域进行插值。 We define the gradient direction by a unit vector v. 通过单位向量v定义了梯度的方向 The values at the corners are then obtained 我们先在要获得图片角上的值,通过什么方式获得呢? by the lengths of the projections of the corner vectors on v. 角落的向量,在V上的投影的长度 A similar approach can be used to create a gradient background for an axes. 同样的方法,可以被用于创建axes的背景色的渐变。 In that case, it is helpful to uses Axes coordinates (extent=(0, 1, 0, 1), transform=ax.transAxes) to be independent of the data coordinates. 在创建axes背景色的渐变时,使用Axes的坐标系,是非常有标注的。这样做可以独立数据坐标系。 """ import matplotlib.pyplot as plt import numpy as np np.random.seed(19680801) def gradient_image(ax, extent, direction=0.3, cmap_range=(0, 1), **kwargs): """ Draw a gradient image based on a colormap. 基于colormap 生成一个有颜色有梯度变化的图片 Parameters ---------- ax : Axes 坐标系 The axes to draw on.图片就画在这个坐标系里面 extent The extent of the image as (xmin, xmax, ymin, ymax). 图片绘画的范围,xmin和xMax标注了,在x轴方向的范围;ymin和ymax标注了在y轴方向的范围; By default, this is in Axes coordinates but may be changed using the *transform* keyword argument. 默认情况下,使用Axes的坐标系,如果想改坐标系可以使用transform的坐标系。 direction : float The direction of the gradient. 颜色梯度的变化范围内。 This is a number in range 0 (=vertical) to 1 (=horizontal). 如果是0就是垂直的,1就是水平的。 cmap_range : float, float The fraction (cmin, cmax) of the colormap that should be used for the gradient, where the complete colormap is (0, 1). 这个参数控制颜色范围,在范围必须在0到1之间选一个范围 **kwargs Other parameters are passed on to `.Axes.imshow()`. In particular useful is *cmap*. 其它的一些参数,传递给Axes.imshow().对cmap非常有用。 """ """ 如果direction是水平方向的,direction=0,phi=0 如果direction是垂直方向的,direction=1,phi=3.14/2=1.57 """ phi = direction * np.pi / 2 """ 新建一个numpy数组,数据维度为一行两列 """ v = np.array([np.cos(phi), np.sin(phi)]) """ 这个的@,是代表两个numpy数组进行叉乘。 """ print(v @ [1,0]) print(v*[1,0]) """ 渐变范围: 图像四个角的颜色 """ X = np.array([[v @ [1, 0], v @ [1, 1]], [v @ [0, 0], v @ [0, 1]]]) """ cmpa_range 是颜色范围; 这是一个解包的过程,a为最小值,b为最大值 """ a, b = cmap_range """ 对颜色进行归一化,将颜色归一化到a,b之间 这里采用的是最大值归一化,步骤如下: 第一步:X/X.max(): 这一步是将X中的数全部变成小数 第二步:X/X.max() * (b-a) 这一步是将X中的值,变成0到b-a之间的值 第三步:X/X.max() * (b-a)+a 这一步是将X中的值,变成a到b之间的值 对上面的式子,采用交换律就得到了下面的式子 """ X = a + (b - a)* X/ X.max() """ X 带表了颜色的范围; extent 字面意思是范围的意思,指定了画图的范围; interpolation: 指定了颜色的填充值的算法 vmin,vmax 指定颜色覆盖的数据范围 """ im = ax.imshow(X, extent=extent, interpolation="bicubic", vmin=0, vmax=1, **kwargs) return im def gradient_bar(ax, x, y, width=0.5, bottom=0): """ 这个方法完成柱子的渐变,计算每个柱子的范围。 :param ax: :param x: :param y: :param width: :param bottom: :return: """ for left, top in zip(x, y): """ left 是柱子的最左边的x轴对应的值 top 是柱子的高度,是y方向的值 right 是柱子最右边的x轴对应的值 bottom 是柱子最底部的值 这里描述了一个长方形,并不是用坐标系描述的;所谓的坐标系描述方法: 在一个坐标系中定义一个长方形,需要四个点,对应长方形的四个角的坐标 而是用 范围描述的:范围描述是,直接在坐标系中切四刀,然后就构成了一个矩阵。 """ right = left + width """ cmap 指定了色系 cmpa_range 指定了色系的变化范围 """ gradient_image(ax, extent=(left, right, bottom, top), cmap=plt.cm.Blues_r, cmap_range=(0, 0.8)) """ x 轴的最大值和最小值 """ xmin, xmax = xlim = 0, 10 """ y 轴的最小值和最大值 """ ymin, ymax = ylim = 0, 1 fig, ax = plt.subplots() """ 设置坐标系的范围, xlim: 设置x轴的范围 ylim: 设置y轴的范围 autoscale_on,不能进行自动缩放 """ ax.set(xlim=xlim, ylim=ylim, autoscale_on=False) # background image """ 设置背景色 direction = 1 为水平方向 extent=(0,1,0,1)代表百分之百 transform = ax.transAxes 代表用axes的坐标系 cmap 指定颜色 cmap_range 指定颜色范围 """ gradient_image(ax, direction=1, extent=(0, 1, 0, 1), transform=ax.transAxes, cmap=plt.cm.RdYlGn, cmap_range=(0.2, 0.8), alpha=0.5) """ 代表要画的柱子数据 """ N = 10 """ 代表每个柱子在x轴的坐标 """ print(np.arange(10)) x = np.arange(N) + 0.15 """ 代表每个柱子的高度 """ y = np.random.rand(N) gradient_bar(ax, x, y, width=0.7) """ Set the aspect of the axis scaling 设置轴的缩放: equal : same scaling for x and y auto : fll the position rectangle with data """ ax.set_aspect("auto") plt.show()