2012-02-06 11 views
31

C'è un modo in matplotlib per specificare parzialmente il colore di una stringa?Colorazione parziale del testo in matplotlib

Esempio:

plt.ylabel("Today is cloudy.") 

Come posso mostrare "oggi" in rosso "è" il verde e "nuvoloso". come blu?

Grazie.

+2

Penso che dovresti modificarlo con 3 caselle di testo separate. – wim

+0

Chiedi alla mailing list matplotlib. Potrebbe essere possibile con il renderizzatore personalizzato o "Artista", forse. –

+1

Anche a https://github.com/matplotlib/matplotlib/issues/697 –

risposta

18

So solo come farlo in modo non interattivo, e anche solo con il backend 'PS'.

Per fare questo, vorrei usare Latex per formattare il testo. Quindi includo il pacchetto "colore" e imposto i colori come preferisci.

Ecco un esempio di fare questo:

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') 

Ciò si traduce in (convertito da ps in PNG usando ImageMagick, così ho potuto postare qui): enter image description here

+1

userei questo, se solo dovesse funzionare con il back-end in formato PDF :) Per qualche ragione, non riesco mai a posizionare correttamente gli assi su la tela mentre sto lavorando con il backend ps. –

+0

Mi dispiace, non volevo minimizzare questo. Avevo intenzione di svenderlo e devo averlo scritto male in precedenza. – mixedmath

+0

Soluzione molto bella. C'è un modo per creare 'pdf'? A parte salvarlo come 'ps' e poi' ps2pdf', che praticamente rovina tutto nel mio grafico ... –

18

ecco la versione interattiva (stessa che ho postato per the list)

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.5,0.5,"all unicorns poop rainbows ! ! !".split(), 
     ['red', 'orange', 'brown', 'green', 'blue', 'purple', 'black'], 
     size=40) 

all unicorns poop rainbows

+0

Sembra che le parole non siano esattamente allineate nella versione verticale. – Alex

+1

Questo era in realtà un bug in matplotlib nel momento in cui ho scritto quel commento. Da allora è stato corretto, come puoi vedere [qui] (http://matplotlib.org/examples/text_labels_and_annotations/rainbow_text.html). –

4

Estendere la risposta di Yann, colorazione LaTeX ora also works with PDF export:

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") 

Si noti che questo script python a volte non riesce con Undefined control sequence errori nel primo tentativo. Eseguirlo di nuovo è quindi un successo.

Problemi correlati