文本部分着色

2025-02-11 09:51:00
admin
原创
49
摘要:问题描述:matplotlib 中有没有办法部分指定字符串的颜色?例子:plt.ylabel("Today is cloudy.") 我怎样才能将“今天”显示为红色、将“是”显示为绿色并将“多云”显示为蓝色?解决方案 1:我只知道如何以非交互方式执行此操作,而且只能使用“PS”后端。为此,...

问题描述:

matplotlib 中有没有办法部分指定字符串的颜色?

例子:

plt.ylabel("Today is cloudy.")

我怎样才能将“今天”显示为红色、将“是”显示为绿色并将“多云”显示为蓝色?


解决方案 1:

我只知道如何以非交互方式执行此操作,而且只能使用“PS”后端。

为此,我将使用 Latex 来格式化文本。然后我将包含“颜色”包,并根据需要设置颜色。

下面是一个示例:

import matplotlib
matplotlib.use('ps')
from matplotlib import rc

rc('text',usetex=True)
rc('text.latex', preamble=r'/usepackage{color}')
import matplotlib.pyplot as plt

plt.figure()
plt.ylabel(r'    extcolor{red}{Today} '+
           r'    extcolor{green}{is} '+
           r'    extcolor{blue}{cloudy.}')
plt.savefig('test.ps')

结果是(使用 ImageMagick 从 ps 转换为 png,因此我可以将其发布在这里):
在此处输入图片描述

解决方案 2:

这是交互式版本。编辑:修复了 Matplotlib 3 中产生多余空格的错误。

import matplotlib.pyplot as plt
from matplotlib import transforms

def rainbow_text(x,y,ls,lc,**kw):
    """
    Take a list of strings ``ls`` and colors ``lc`` and place them next to each
    other, with text ls[i] being shown in color lc[i].

    This example shows how to do both vertical and horizontal text, and will
    pass all keyword arguments to plt.text, so you can set the font size,
    family, etc.
    """
    t = plt.gca().transData
    fig = plt.gcf()
    plt.show()

    #horizontal version
    for s,c in zip(ls,lc):
        text = plt.text(x,y,s+" ",color=c, transform=t, **kw)
        text.draw(fig.canvas.get_renderer())
        ex = text.get_window_extent()
        t = transforms.offset_copy(text._transform, x=ex.width, units='dots')

    #vertical version
    for s,c in zip(ls,lc):
        text = plt.text(x,y,s+" ",color=c, transform=t,
                rotation=90,va='bottom',ha='center',**kw)
        text.draw(fig.canvas.get_renderer())
        ex = text.get_window_extent()
        t = transforms.offset_copy(text._transform, y=ex.height, units='dots')


plt.figure()
rainbow_text(0.05,0.05,"all unicorns poop rainbows ! ! !".split(), 
        ['red', 'orange', 'brown', 'green', 'blue', 'purple', 'black'],
        size=20)

在此处输入图片描述

解决方案 3:

扩展Yann 的答案,LaTeX 着色现在也适用于 PDF 导出:

import matplotlib
from matplotlib.backends.backend_pgf import FigureCanvasPgf
matplotlib.backend_bases.register_backend('pdf', FigureCanvasPgf)

import matplotlib.pyplot as plt

pgf_with_latex = {
    "text.usetex": True,            # use LaTeX to write all text
    "pgf.rcfonts": False,           # Ignore Matplotlibrc
    "pgf.preamble": [
        r'/usepackage{color}'     # xcolor for colours
    ]
}
matplotlib.rcParams.update(pgf_with_latex)

plt.figure()
plt.ylabel(r'    extcolor{red}{Today} '+
           r'    extcolor{green}{is} '+
           r'    extcolor{blue}{cloudy.}')
plt.savefig("test.pdf")

请注意,此 Python 脚本有时会Undefined control sequence在第一次尝试时失败并出现错误。再次运行它就会成功。

解决方案 4:

尝试了以上所有方法后,我又回到了我的愚蠢但简单的方法,使用plt.text。唯一的问题是你需要调整每个单词之间的间距。你可能需要多次调整位置,但我还是喜欢这种方式,因为它

  1. 省去了安装 tex 编译器的麻烦,

  2. 不需要任何特殊的后端,并且

  3. 免除你配置 matplotlib rc 并配置回来的麻烦,否则由于 usetex=True,它可能会减慢你的其他绘图速度

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
label_x = -0.15
ax.text(label_x, 0.35, r"Today", color='red', rotation='vertical', transform=ax.transAxes)
ax.text(label_x, 0.5, r"is", color='green', rotation='vertical', transform=ax.transAxes)
ax.text(label_x, 0.55, r"cloudy", color='blue', rotation='vertical', transform=ax.transAxes)

在此处输入图片描述

解决方案 5:

以下内容基于@Paul Ivanov上述的精彩回答;如果这对您有用,请对他的回答点赞。

我稍微修改了他的代码:

  1. 处理hahorizo​​ntalalignment)关键字参数。

  2. 使 pdf 输出正常工作(需要在pointsnot中工作dots)。

  3. 有一个稍微“更好”的 API,用于为几个单词着色。

您可以在下面看到该功能及其使用方法:

import matplotlib.pyplot as plt
from matplotlib import transforms


def multicolored_text(x, y, text, cd, **kw):
    """
    Place text at (x, y) with colors for each word specified in the color
    dictionary cd, which maps strings to colors, and must include a 'default'
    key mapping to the default color.

    Based on https://stackoverflow.com/a/9185851/2683, thanks paul ivanov!
    """
    fig = plt.gcf()
    t = plt.gca().transData

    def get_text_width(text, **kw):
        temp = plt.text(0, 0, text, **kw)
        temp.draw(fig.canvas.get_renderer())
        ex = temp.get_window_extent()
        # Need the text width in data coordinates, since that's what x uses.
        width = t.inverted().transform_bbox(ex).width
        temp.remove()
        return width

    ha = kw.pop('ha', 'left')
    match ha:
        case 'left':
            x = x
        case 'center':
            x -= get_text_width(text, **kw) / 2
        case 'right':
            x -= get_text_width(text, **kw)
        case _:
            raise ValueError(f'invalid value for horizontal alignment {ha}')

    for word in text.split(' '):
        c = cd.get(word, cd['default'])
        text = plt.text(x, y, word + ' ', color=c, transform=t, **kw)
        text.draw(fig.canvas.get_renderer())
        ex = text.get_window_extent()
        # Need the text width in points so that this will work with pdf output.
        width = ex.width / fig.dpi * 72  # Can do via fig.dpi_scale_trans?

        t = transforms.offset_copy(text._transform, x=width, units='points', fig=fig)


plt.figure()
text = "One does not simply use multicolored text"
colors = {
    'default': 'black',
    'simply': 'red',
    'multicolored': 'blue',
}
multicolored_text(.5, .05, text, colors, ha='center', size=20)

Matplotlib 绘制带有彩色文本的图

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用