我正在try 绘制渐变文本.我的 idea 是使用代码from the docs创建渐变,创建渐变背景,然后使用文本路径裁剪图像.不管是什么原因,我只收到了第一个字母和一些第二个字母.

enter image description here

更改轴的限制或图形的宽度似乎不起作用.我可以更改TextPath的大小,但似乎无法使文本占据图像的全部大小.将文本大小设置为0.2并将YLIM从0设置为0.2只会生成压缩文本.如何才能使文本跨过轴的大小并获得整个渐变的范围?

enter image description here

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import matplotlib.textpath
import matplotlib.patches
import numpy as np


def gradient_image(ax, extent, direction=0.3, cmap_range=(0, 1), **kwargs):
    """
    Draw a gradient image based on a colormap.

    Parameters
    ----------
    ax : Axes
        The axes to draw on.
    extent
        The extent of the image as (xmin, xmax, ymin, ymax).
        By default, this is in Axes coordinates but may be
        changed using the *transform* keyword argument.
    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 useful is *cmap*.
    """
    phi = direction * np.pi / 2
    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
    X = a + (b - a) / X.max() * X
    im = ax.imshow(X, extent=extent, interpolation='bicubic',
                   vmin=0, vmax=1, **kwargs)
    return im


fig, ax = plt.subplots(figsize=(1,1))

im = gradient_image(ax, direction=1, extent=(0, 1, 0, 1), transform=ax.transAxes,
               cmap=plt.cm.winter, cmap_range=(0.2, 0.8), alpha=0.5)

fp = FontProperties(family='DejaVu Sans', weight='bold')
text = matplotlib.textpath.TextPath((0.0, 0.0), 'ABCDEFG',
                                             size=1, prop=fp)

im.set_clip_path(text, transform=ax.transAxes)

# ax.set_xticks(())
# ax.set_yticks(())
# ax.tick_params(width=0, which='both')
# ax.set_xlim((0, 10))
# ax.set_ylim((0, 1))
for spine in ['top', 'bottom', 'left', 'right']:
    ax.spines[spine].set_visible(False)

推荐答案

我对matplotlib transformations不是很流利,但从我所阅读的内容来看,ax.TransData似乎是更好的方法(注释是我更改了您的代码):

enter image description here

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import matplotlib.textpath
import matplotlib.patches
import numpy as np


def gradient_image(ax, extent, direction=0.3, cmap_range=(0, 1), **kwargs):
    """
    Draw a gradient image based on a colormap.

    Parameters
    ----------
    ax : Axes
        The axes to draw on.
    extent
        The extent of the image as (xmin, xmax, ymin, ymax).
        By default, this is in Axes coordinates but may be
        changed using the *transform* keyword argument.
    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 useful is *cmap*.
    """
    phi = direction * np.pi / 2
    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
    X = a + (b - a) / X.max() * X
    # added origin = lower, elsewise text is flipped upside down
    im = ax.imshow(X, extent=extent, interpolation='bicubic',
                   vmin=0, vmax=1, origin='lower', **kwargs)
    return im


fig, ax = plt.subplots(figsize=(1, 1))

# define text before gradient to get extent
fp = FontProperties(family='DejaVu Sans', weight='bold')
text = matplotlib.textpath.TextPath((0.0, 0.0), 'ABCDEFG',
                                    size=1, prop=fp)
# use text to define imshow extent
extent = text.get_extents().extents[[0, 2, 1, 3]]
im = gradient_image(ax, direction=1, extent=extent,
                    cmap=plt.cm.winter, cmap_range=(0.2, 0.8), alpha=0.5)

# use transData instead of transAxes
im.set_clip_path(text, transform=ax.transData)
# © trenton
ax.spines[['top', 'bottom', 'left', 'right']].set_visible(False)

plt.show()

Python相关问答推荐

决策树分类器的基础sklearn熵和log_loss标准是否有差异?

在for循环中保存和删除收件箱

如何修复fpdf中的线路出血

为什么使用SciPy中的Distance. cos函数比直接执行其Python代码更快?

如何将自动创建的代码转换为类而不是字符串?

如何将带有逗号分隔的数字的字符串解析为int Array?

如何使用Tkinter创建两个高度相同的框架(顶部和底部)?

如何将桌子刮成带有Se的筷子/要求/Beautiful Soup ?

使用多个性能指标执行循环特征消除

如何根据情况丢弃大Pandas 的前n行,使大Pandas 的其余部分完好无损

在函数内部使用eval(),将函数的输入作为字符串的一部分

如何在Deliveryter笔记本中从同步上下文正确地安排和等待Delivercio代码中的结果?

我在使用fill_between()将最大和最小带应用到我的图表中时遇到问题

Matlab中是否有Python的f-字符串等效物

根据在同一数据框中的查找向数据框添加值

从groupby执行计算后创建新的子框架

如何让这个星型模式在Python中只使用一个for循环?

在单个对象中解析多个Python数据帧

为什么\b在这个正则表达式中不解释为反斜杠

为什么'if x is None:pass'比'x is None'单独使用更快?