Is there a way in matplotlib to partially specify the color of a string?
Example:
plt.ylabel("Today is cloudy.")
How can I show "today" as red, "is" as green and "cloudy." as blue?
I only know how to do this non-interactively, and even then only with the 'PS' backend.
To do this, I would use Latex to format the text. Then I would include the 'color' package, and set your colors as you wish.
Here is an example of doing this:
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')
This results in (converted from ps to png using ImageMagick, so I could post it here):
Here's the interactive version. Edit: Fixed bug producing extra spaces in 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)
Extending Yann's answer, LaTeX coloring now 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")
Note that this python script sometimes fails with Undefined control sequence
errors in the first attempt. Running it again is then successful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With