52 votes

Coloration partielle du texte dans matplotlib

Existe-t-il un moyen dans matplotlib de spécifier partiellement la couleur d'une chaîne?

Exemple:

 plt.ylabel("Today is cloudy.")

Comment puis-je afficher "aujourd'hui" en rouge, "est" en vert et "nuageux". comme bleu ?

Merci.

32voto

Yann Points 6909

Je ne sais comment faire cela que de manière non interactive, et même alors uniquement avec le backend 'PS'.

Pour ce faire, j'utiliserais du latex pour formater le texte. Ensuite, j'inclurais le package « couleur » et définirais vos couleurs comme vous le souhaitez.

Voici un exemple de réalisation :

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

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

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

Cela donne (converti de ps en png à l'aide d'ImageMagick, donc je pourrais le poster ici): entrez la description de l'image ici

27voto

Paul Ivanov Points 991

Voici la version interactive. Edit : Correction d'un bug produisant des espaces supplémentaires dans 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)

entrez la description de l'image ici

10voto

Felix Points 539

Prolongeant la réponse de Yann, la coloration LaTeX fonctionne désormais également avec l'export 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'\textcolor{red}{Today} '+
           r'\textcolor{green}{is} '+
           r'\textcolor{blue}{cloudy.}')
plt.savefig("test.pdf")

Notez que ce script python échoue parfois avec des Undefined control sequence lors de la première tentative. L'exécuter à nouveau est alors réussi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X