Matplotlib: цветной текст в легенде вместо строки

на некоторых ЖК-мониторах цвет горизонтальных линий в легенде трудно различить. (См. прилагаемое изображение). Итак, вместо того, чтобы рисовать линию в легенде, можно ли просто раскрасить сам текст? Итак, другие слова:" y=0x " в синем," y=1x " в зеленом и т. д...

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()

enter image description here

PS. если бы линию можно было сделать толще только в легенде, но не в сюжете, это тоже сработало бы.

4 ответов


просто установить linewidth легенды ручки:

In [55]: fig, ax = plt.subplots()

In [56]: x = np.arange(10)

In [57]: for i in xrange(5):                    
   ....:     ax.plot(x, i * x, label='$y = %ix$' % i)
   ....:     

In [58]: leg = ax.legend(loc='best')

In [59]: for l in leg.legendHandles:            
   ....:     l.set_linewidth(10)
   ....:     

legend_linewidth.png


мне было интересно то же самое. Вот что я придумал, чтобы изменить цвет шрифта в легенде. Я не совсем доволен этим методом, так как он кажется немного неуклюжим, но, похоже, он выполняет работу [Edit: см. ниже для лучшего способа]:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

colors = []
for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$' % i)
    colors.append(plt.getp(line,'color'))

leg = ax.legend()

for color,text in zip(colors,leg.get_texts()):
    text.set_color(color)

plt.show()

the colorful results

2016 Edit:

на самом деле, есть способ лучше. Вы можете просто перебирать строки в легенде, что позволяет избежать необходимости отслеживать цвета, как линии подготовленный. Гораздо менее неуклюжим. Теперь изменение цвета линии в основном является однострочным (хорошо, на самом деле это два вкладыша). Вот полный пример:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i*x, label='$y = %ix$'%i)

leg = ax.legend()

# change the font colors to match the line colors:
for line,text in zip(leg.get_lines(), leg.get_texts()):
    text.set_color(line.get_color())

plt.show()

2017 Edit: наконец, если вы действительно хотите цветной текст вместо строки (как следует из названия), затем вы можете подавить строки в легенде, используя

 leg = ax.legend(handlelength=0)

эта операция может быть выполнена чисто после того, как все построение выполняется с помощью геттеров/сеттеров текста легенды и геттеров/сеттеров линии оси. Установите цвета текста легенды такими же, как цвета линий в цикле for перед построением графика.

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

leg = ax.legend()

def color_legend_texts(leg):
    """Color legend texts based on color of corresponding lines"""
    for line, txt in zip(leg.get_lines(), leg.get_texts()):
        txt.set_color(line.get_color())  

color_legend_texts(leg)    

plt.show()

основное отличие в этом ответе заключается в том, что форматирование графика может быть полностью отделено от операции построения.


чтобы предоставить более общее решение для раскрашивания текста легенды цветом дескриптора легенды: Это работает не только для линий, но и для любого художника в легенде. Это выглядело бы следующим образом:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)


ax.plot(x, 3 * x, label='$y = %ix$' % 3)
ax.scatter(x, 4 * x, color="red", label='$y = %ix$' % 4)
ax.hist(x, label="hist")
ax.errorbar(x,2*x,yerr=0.3*x, label='$y = %ix$' % 2)

leg = ax.legend()

for artist, text in zip(leg.legendHandles, leg.get_texts()):
    try:
        col = artist.get_color()
    except:
        col = artist.get_facecolor()
    if isinstance(col, np.ndarray):
        col = col[0]
    text.set_color(col)

plt.show()

enter image description here