1

I'm using matplotlib 3.4.3, ubuntu 20.04, and Python 3.8 .I'm trying to change the label color with multicolors, but it shows black color without giving any error. I have installed all packages and tried differents examples without any success. Also, I have multiple labels that need different colors which makes it difficult to arrange them manually.

sudo apt-get install texlive-latex-base texlive-fonts-recommended texlive-fonts-extra texlive-latex-extra

import matplotlib.pyplot as plt


plt.rcParams['text.usetex'] = True
plt.rcParams['text.latex.preamble'] =r"\usepackage{xcolor} "
_, ax = plt.subplots()

plt.plot([0, 1], [0, 1], 'r')
plt.plot([0, 1], [0, 2], 'b')


plt.ylabel(r"\color{blue}{y} "+r"\textcolor{red}{label} ")

plt.savefig('test.pdf')
plt.show()

label color

I_Al-thamary
  • 3,385
  • 2
  • 24
  • 37
  • possibly helpful: https://matplotlib.org/stable/gallery/text_labels_and_annotations/rainbow_text.html#sphx-glr-gallery-text-labels-and-annotations-rainbow-text-py – tmdavison Oct 18 '21 at 09:43
  • Thanks, I have tried and it is on the link shown in the questions and it works but it is not matched what I need because every point in the loop needs to have a label with different colors. – I_Al-thamary Oct 18 '21 at 09:46
  • @tmdavison how can make it colors the `plt.ylabel` because it shows the text in the figures not in the label. – I_Al-thamary Oct 18 '21 at 10:02
  • It seems to me that the _y_ label is not rendered by TeX, look at the typeface that was used. – gboffi Oct 18 '21 at 10:57
  • 1
    it is latex; it's using the sans-serif font, while the tick labels are using the serif font. try adding some math-mode text in the y label to check (e.g. put something between `$$`) – tmdavison Oct 18 '21 at 12:08
  • but this seems to be a known issue: https://github.com/matplotlib/matplotlib/issues/6724 – tmdavison Oct 18 '21 at 12:12
  • @tmdavison it has shown the latex symbol but not the color. – I_Al-thamary Oct 18 '21 at 15:04

2 Answers2

4

This appears to be a known issue with many of the matplotlib backends. For example, see here: https://github.com/matplotlib/matplotlib/issues/6724

One potential solution, as suggested here, is to save the figure in ps format, and then convert to pdf later.

For example:

import matplotlib.pyplot as plt


plt.rcParams['text.usetex'] = True
plt.rcParams['text.latex.preamble'] =r"\usepackage{xcolor} "
_, ax = plt.subplots()

plt.plot([0, 1], [0, 1], 'r')
plt.plot([0, 1], [0, 2], 'b')


plt.ylabel(r"\color{blue}{y} "+r"\textcolor{red}{label} ")

plt.savefig('test.ps')

and then, in a terminal

ps2pdf test.ps

Below is a screenshot of the resulting test.pdf file:

enter image description here

Note: tested on python 3.7.10, matplotlib 3.4.2, MacOS 10.15.7

tmdavison
  • 64,360
  • 12
  • 187
  • 165
1

The answers by tmdavison only support the ps format. So, I tried to solve the problem to accept any format. To show how I solve this problem, I provide a dataset that makes the whole idea sample to understand. In my case, I have more than 34 figures with different points, and every point needs to be described. I use this code, and I added the x=min(x-axis) and y=median(y-axis).

Here is the content of the emp.csv

enter image description here

import pandas as pd
from matplotlib import pyplot as plt
from matplotlib.transforms import Affine2D
import os
cwd = os.path.dirname(__file__)

def rainbow_text(x, y, strings, colors, orientation='vertical',
                 ax=None, **kwargs):
    if ax is None:
        ax = plt.gca()
    t = ax.transData
    canvas = ax.figure.canvas

    assert orientation in ['horizontal', 'vertical']
    if orientation == 'vertical':
        kwargs.update(rotation=90, verticalalignment='bottom')

    for s, c in zip(strings, colors):
        text = ax.text(x, y, s + " ", color=c, transform=t, **kwargs)

        # Need to draw to update the text position.
        text.draw(canvas.get_renderer())
        ex = text.get_window_extent()
        if orientation == 'horizontal':
            t = text.get_transform() + Affine2D().translate(ex.width, 0)
        else:
            t = text.get_transform() + Affine2D().translate(0, ex.height)
df = pd.read_csv('emp.csv', error_bad_lines=False)
colors_ = ['black', 'red', 'black', 'red']
i=0
for row in df.itertuples(index=True, name='Pandas'):

    plt.scatter(getattr(row, "sal"), getattr(row, "inc"), color = 'b', s=10)
    word = ['First name=', str(getattr(row, "first_name")), 'Last name=', str(getattr(row, "last_name"))]
    rainbow_text(df["sal"].min()-8.3, df["inc"].median()-1.2, word, colors_, size=5)
    word = ['age=', str(getattr(row, "age")), 'gender=', str(getattr(row, "gender"))]
    rainbow_text(df["sal"].min()-7.8, df["inc"].median()-1.2, word, colors_, size=5)
    plt.savefig(os.path.join(cwd, 'fig/Test_fig_' + str(i) + '.pdf'), format='pdf', dpi=600, bbox_inches='tight')
    i += 1
    plt.show()

enter image description here

I_Al-thamary
  • 3,385
  • 2
  • 24
  • 37