python画图|自制渐变柱状图

在前述学习过程中,我们已经通过官网学习了如何绘制渐变的柱状图及其背景。

掌握一门技能的最佳检验方式就是通过实战,因此,本文尝试做一些渐变设计。

前述学习记录可查看链接:

Python画图|渐变背景-CSDN博客

 【1】柱状图渐变

在上一篇文章中,由于代码太长,对单个函数的解读不够详细,在本文中可以详细展开。

首先将背景渐变的代码改为注释,原因为:

【a】所有渐变都使用了gradient_image()函数;

【b】gradient_bar()函数通过调用gradient_image()函数画出了渐变的柱状图;

【c】调用gradient_image()函数单独定义了背景渐变。

因此,在不对代码进行修改的前提下,最快速的更改就是把背景渐变的代码消除:

# background image
#gradient_image(ax, direction=1, extent=(0, 1, 0, 1), transform=ax.transAxes,
               #cmap=plt.cm.RdYlGn, cmap_range=(0.2, 0.9), alpha=0.5) #调用了子函数

此时的输出结果为:

图1

由图1可见,坐标轴区域内部已经改为纯色,仅柱状图变成渐变颜色。

然后尝试修改颜色,将柱状图的渐变色改为cmap由plt.cm.Blues_r改为plt.cm.Blues,此时的输出结果为:

图2

对比图1和图2可见,渐变的方向进行了交换。

【2】渐变代码解读

经过追溯, gradient_bar()函数和gradient_image()函数的构造和使用基本上都参考了ax.imshow()函数。

【2.1】ax.imshow()函数

因,在实施渐变以前,有必要先学习ax.imshow()函数:

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.imshow.html#matplotlib.axes.Axes.imshow

Axes.imshow(X, cmap=None, norm=None, *, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, interpolation_stage=None, filternorm=True, filterrad=4.0, resample=None, url=None, data=None, **kwargs)

ax.imshow()包含参数意义如下:

X:画图数据依据

cmap:颜色参数

norm:标准化工具,将cmap数据缩放到(0,1)范围

aspect:设定坐标轴的长宽比

interpolation:插值设置

alpha:透明度设置

origin:设定数组的起点在左下角还是左上角

extent:边界框

interpolation_stage:插值范围

filternorm:图像粒度调整

filterrad=与差值先关

其余如resample、url、data=None和**kwargs不常用,暂无需关注。

【2.2】gradient_bar()函数

基于此,我们尝试解读下述代码:

def gradient_bar(ax, x, y, width=0.5, bottom=0): #自定义函数
    for left, top in zip(x, y):
        right = left + width #右边等于左边加宽度,这是要逐个排列的意思
        gradient_image(ax, extent=(left, right, bottom, top),
                       cmap=plt.cm.Blues##, cmap_range=(0.2, 0.9)

第一行:

def gradient_bar(ax, x, y, width=0.5, bottom=0): #自定义函数

其中的ax,x,y均为外部输入变量, width=0.5, bottom=0为内部已经完成定义的变量。

for函数对x和y组成的组合数组进行取值。

right是内部变量,left+width代表着柱状图不断右移。

gradient_image()函数在此处被直接调用,调用的时候只需要外部输入ax,其余参数如extent、cmap和cmap_range都已经提前完成了赋值。

【2.3】gradient_image()函数

基于前述分析,我们尝试解读下述代码:

# background image
gradient_image(ax, direction=1, extent=(0, 1, 0, 1), transform=ax.transAxes,
               cmap=plt.cm.RdYlGn, cmap_range=(0.2, 0.9), alpha=0.5) #调用了子函数

这里是对gradient_image()函数的直接调用,几乎所有参数都已经解读过,稍有变化的是里面多了一个transform参数,这里的transform=ax.transAxes就是把ax值转化为Axes值 ,顺直坐标轴画直方图的意思。

【3】渐变调控

根据前述分析已经知晓,柱状图渐变和背景渐变可以分别设置,因此,此处尝试消除柱状图渐变,然后恢复背景渐变。

【3.1】柱状图渐变

消除柱状图渐变,最快的方式是将cmap_range的赋值改成一致的即可:

def gradient_bar(ax, x, y, width=0.5, bottom=0): #自定义函数
    for left, top in zip(x, y):
        right = left + width #右边等于左边加宽度,这是要逐个排列的意思
        gradient_image(ax, extent=(left, right, bottom, top),
                       cmap=plt.cm.Blues, cmap_range=(0.8, 0.8))

此时的输出图像为:

图3

【3.2】背景渐变

消除背景图渐变,最快的方式也是将cmap_range的赋值改成一致的即可:

# background image
gradient_image(ax, direction=1, extent=(0,1,0, 1), transform=ax.transAxes,
               cmap=plt.cm.RdYlGn, cmap_range=(0.9, 0.9), alpha=0.5) #调用了子函数

 此时的输出图像为:

图4

至此,所有渐变已经消除。

至此的完整代码为:

import matplotlib.pyplot as plt  # 引入matplotlib模块画图
import numpy as np  # 引入numpy模块做数学计算

np.random.seed(19680801) #定义随机数种子


def gradient_image(ax, direction=0.3, cmap_range=(0, 1), **kwargs): #自定义函数
    """
    Draw a gradient image based on a colormap.

    Parameters
    ----------
    ax : Axes
        The Axes to draw on.
    direction : float
        The direction of the gradient. This is a number in
        range 0 (=vertical) to 1 (=horizontal).
    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).
    **kwargs
        Other parameters are passed on to `.Axes.imshow()`.
        In particular, *cmap*, *extent*, and *transform* may be useful.
    """
    phi = direction * np.pi / 2 #定义因变量,从np.pi可以看出这是一个角度变量
    v = np.array([np.cos(phi), np.sin(phi)]) #定义数组,包括正弦值和余弦值
    X = np.array([[v @ [1, 0], v @ [1, 1]],
                  [v @ [0, 0], v @ [0, 1]]]) #这里的@是矩阵乘法
    a, b = cmap_range #定义变量a和b
    X = a + (b - a) / X.max() * X #定义变量X
    im = ax.imshow(X, interpolation='bicubic', clim=(0, 1),
                   aspect='auto', **kwargs) #定义变量im
    return im #返回im


def gradient_bar(ax, x, y, width=0.5, bottom=0): #自定义函数
    for left, top in zip(x, y):
        right = left + width #右边等于左边加宽度,这是要逐个排列的意思
        gradient_image(ax, extent=(left, right, bottom, top),
                       cmap=plt.cm.Blues, cmap_range=(0.8, 0.8))


fig, ax = plt.subplots()
ax.set(xlim=(0, 10), ylim=(0, 1))

# background image
gradient_image(ax, direction=1, extent=(0,1,0, 1), transform=ax.transAxes,
               cmap=plt.cm.RdYlGn, cmap_range=(0.9, 0.9), alpha=0.5) #调用了子函数

N = 10 #定义常量10
x = np.arange(N) + 0.15 #使用随机变量参与运算制造变量x
y = np.random.rand(N) #定义随机矩阵
gradient_bar(ax, x, y, width=0.7) #画随机柱状图
plt.show() #输出图形

【4】坐标轴外背景颜色设置

在前述学习过程中,已经讨论了坐标轴以外的颜色设置,详见下述链接:

python画图|图像背景颜色设置-CSDN博客

此处的渐变仅仅涉及坐标轴内部区域和柱状图本身,基于此,尝试设置坐标轴外部的颜色,修改画图代码为:

fig, ax = plt.subplots(facecolor=(0.6, 0.5,0.9))

此时的输出结果为:

图5

由图5可见,外部背景、坐标轴内都有了颜色。

此时的完整代码为:

import matplotlib.pyplot as plt  # 引入matplotlib模块画图
import numpy as np  # 引入numpy模块做数学计算

np.random.seed(19680801) #定义随机数种子


def gradient_image(ax, direction=0.3, cmap_range=(0, 1), **kwargs): #自定义函数
    """
    Draw a gradient image based on a colormap.

    Parameters
    ----------
    ax : Axes
        The Axes to draw on.
    direction : float
        The direction of the gradient. This is a number in
        range 0 (=vertical) to 1 (=horizontal).
    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).
    **kwargs
        Other parameters are passed on to `.Axes.imshow()`.
        In particular, *cmap*, *extent*, and *transform* may be useful.
    """
    phi = direction * np.pi / 2 #定义因变量,从np.pi可以看出这是一个角度变量
    v = np.array([np.cos(phi), np.sin(phi)]) #定义数组,包括正弦值和余弦值
    X = np.array([[v @ [1, 0], v @ [1, 1]],
                  [v @ [0, 0], v @ [0, 1]]]) #这里的@是矩阵乘法
    a, b = cmap_range #定义变量a和b
    X = a + (b - a) / X.max() * X #定义变量X
    im = ax.imshow(X, interpolation='bicubic', clim=(0, 1),
                   aspect='auto', **kwargs) #定义变量im
    return im #返回im


def gradient_bar(ax, x, y, width=0.5, bottom=0): #自定义函数
    for left, top in zip(x, y):
        right = left + width #右边等于左边加宽度,这是要逐个排列的意思
        gradient_image(ax, extent=(left, right, bottom, top),
                       cmap=plt.cm.Blues, cmap_range=(0.8, 0.8))


fig, ax = plt.subplots(facecolor=(0.6, 0.5,0.9)) #设置坐标轴外区域颜色
ax.set(xlim=(0, 10), ylim=(0, 1))

# background image
gradient_image(ax, direction=1, extent=(0,1,0, 1), transform=ax.transAxes,
               cmap=plt.cm.RdYlGn, cmap_range=(0.9, 0.9), alpha=0.5) #调用了子函数

N = 10 #定义常量10
x = np.arange(N) + 0.15 #使用随机变量参与运算制造变量x
y = np.random.rand(N) #定义随机矩阵
gradient_bar(ax, x, y, width=0.7) #画随机柱状图
plt.show() #输出图形

【5】自主渐变设置

在前述学习的基础上,给所有区域山上色,并对坐标轴内部区域进行渐变设置,并设置图名为“Gradient Color”。

完整代码为:

import matplotlib.pyplot as plt  # 引入matplotlib模块画图
import numpy as np  # 引入numpy模块做数学计算

np.random.seed(19680801) #定义随机数种子


def gradient_image(ax, direction=0.3, cmap_range=(0, 1), **kwargs): #自定义函数
    """
    Draw a gradient image based on a colormap.

    Parameters
    ----------
    ax : Axes
        The Axes to draw on.
    direction : float
        The direction of the gradient. This is a number in
        range 0 (=vertical) to 1 (=horizontal).
    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).
    **kwargs
        Other parameters are passed on to `.Axes.imshow()`.
        In particular, *cmap*, *extent*, and *transform* may be useful.
    """
    phi = direction * np.pi / 2 #定义因变量,从np.pi可以看出这是一个角度变量
    v = np.array([np.cos(phi), np.sin(phi)]) #定义数组,包括正弦值和余弦值
    X = np.array([[v @ [1, 0], v @ [1, 1]],
                  [v @ [0, 0], v @ [0, 1]]]) #这里的@是矩阵乘法
    a, b = cmap_range #定义变量a和b
    X = a + (b - a) / X.max() * X #定义变量X
    im = ax.imshow(X, interpolation='bicubic', clim=(0, 1),
                   aspect='auto', **kwargs) #定义变量im
    return im #返回im


def gradient_bar(ax, x, y, width=0.5, bottom=0): #自定义函数
    for left, top in zip(x, y):
        right = left + width #右边等于左边加宽度,这是要逐个排列的意思
        gradient_image(ax, extent=(left, right, bottom, top),
                       cmap=plt.cm.Blues, cmap_range=(0.2, 0.8))


fig, ax = plt.subplots(facecolor=(0.6, 0.5,0.9)) #设置坐标轴外区域颜色
ax.set(xlim=(0, 10), ylim=(0, 1))

# background image
gradient_image(ax, direction=1, extent=(0,1,0, 1), transform=ax.transAxes,
               cmap=plt.cm.RdYlGn, cmap_range=(0.1, 0.9), alpha=0.5) #调用了子函数

N = 10 #定义常量10
x = np.arange(N) + 0.15 #使用随机变量参与运算制造变量x
y = np.random.rand(N) #定义随机矩阵
gradient_bar(ax, x, y, width=0.7) #画随机柱状图
ax.set_title('Gradient Color') #设置图名
plt.show() #输出图形

输出图形为:

图6

由图6可见,坐标轴内部的柱状图和背景颜色均渐变,坐标轴外的区域则是纯色。

【6】总结

学习了柱状图、坐标轴区域内部背景颜色的渐变设计,以及为坐标轴外部区域增添颜色。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值