Пользовательская легенда из нескольких строк с двумя маркерами для одного и того же текста

1

Я хотел бы выполнить тип легенды, показанной на рисунке Изображение 174551.

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

На рисунке круги представляют один и тот же параметр, но для двух разных моделей; То же самое верно для треугольных и квадратных маркеров. Я хочу поместить два круговых маркера, ссылающихся на один и тот же параметр в первой строке легенды, и аналогично для двух других маркеров на строках ниже этого. Спасибо.

Код:

import matplotlib.pyplot as plt

q1 = [100.0, 60.0, 200.0, 300.0]
NO1 = [0.35799999999999998, 0.33100000000000002, 0.22900000000000001,     0.17799999999999999]
No1 = [0.34599999999999997, 0.29899999999999999, 0.20699999999999999, 0.14999999999999999]
Nb1 = [0.46600000000000003, 0.45600000000000002, 0.27800000000000002, 0.24399999999999999]

q2 = [60.0, 100.0, 200.0, 300.0]
NO2 = [0.44700000000000001, 0.29199999999999998, 0.28299999999999997, 0.253]
No2 = [0.38900000000000001, 0.28499999999999998, 0.311, 0.251]
Nb2 = [0.44, 0.34899999999999998, 0.45900000000000002, 0.39400000000000002]

fig, ax = plt.subplots(figsize = (6,3))

ax.plot(q1, NO1, marker = 'o', markerfacecolor = 'none', markeredgewidth = 1, color = 'gray', linestyle = '', markersize = 8, label = '$N$ in parameter a')
ax.plot(q2, NO2, marker = 'o', markerfacecolor = 'none', markeredgewidth = 1, color = 'palevioletred', linestyle = '', markersize = 8)#, label = '$N$ in parameter a')
ax.plot(q1, No1, marker = '^', markerfacecolor = 'none', markeredgewidth = 1, color = 'gray', linestyle = '', markersize = 8, label = '$N$ in parameter b')
ax.plot(q2, No2, marker = '^', markerfacecolor = 'none', markeredgewidth = 1, color = 'palevioletred', linestyle = '', markersize = 8)#, label = '$N$ in parameter b')  
ax.plot(q1, Nb1, marker = 's', markerfacecolor = 'none', markeredgewidth = 1, color = 'gray', linestyle = '', markersize = 8, label = '$N$ in parameter c') 
ax.plot(q2, Nb2, marker = 's', markerfacecolor = 'none', markeredgewidth = 1, color = 'palevioletred', linestyle = '', markersize = 8)#, label = '$N$ in parameter c')
#plt.legend(loc='upper right', bbox_to_anchor=(0.945, 1))
plt.xlabel('x')
plt.ylabel('$N$')
plt.xticks([60, 100, 200, 300])
plt.minorticks_on()
plt.tick_params(direction = 'in', bottom = True, top = True, left = True, right = True, which = 'major')    
plt.tick_params(direction = 'in', bottom = False, top = False, left = True, right = True, which = 'minor')  
  • 0
    Это конечно возможно, но не могли бы вы предоставить тестовый пример (т. Е. Код, с которым можно работать). Есть только два разных цвета?
  • 0
    @ImportanceOfBeingErnest Да, только два.
Теги:
matplotlib
legend

1 ответ

1
Лучший ответ

Вы можете использовать обработчик HandlerTuple и предоставлять кортежи артистов, которые будут отображаться в каждой строке как дескрипторы легенды.

import matplotlib.pyplot as plt
import matplotlib.legend_handler

q1 = [100.0, 60.0, 200.0, 300.0]
NO1 = [0.358, 0.331, 0.229, 0.178]
No1 = [0.346, 0.299, 0.207, 0.15]
Nb1 = [0.466, 0.456, 0.278, 0.244]

q2 = [60.0, 100.0, 200.0, 300.0]
NO2 = [0.447, 0.292, 0.283, 0.253]
No2 = [0.389, 0.285, 0.311, 0.251]
Nb2 = [0.44, 0.349, 0.459, 0.394]

fig, ax = plt.subplots(figsize = (6,3))

prop = dict(markerfacecolor = 'none', markeredgewidth = 1,
            linestyle = '', markersize = 8,)
l1, = ax.plot(q1, NO1, marker = 'o', color = 'gray', label = '$N$ in parameter a', **prop)
l2, = ax.plot(q2, NO2, marker = 'o', color = 'palevioletred', **prop)
l3, = ax.plot(q1, No1, marker = '^', color = 'gray', label = '$N$ in parameter b', **prop)
l4, = ax.plot(q2, No2, marker = '^', color = 'palevioletred', **prop)
l5, = ax.plot(q1, Nb1, marker = 's', color = 'gray', label = '$N$ in parameter c', **prop) 
l6, = ax.plot(q2, Nb2, marker = 's', color = 'palevioletred', **prop)


handles = [(l1,l2), (l3,l4), (l5,l6)]
_, labels = ax.get_legend_handles_labels()

ax.legend(handles = handles, labels=labels, loc='upper right', 
          handler_map = {tuple: matplotlib.legend_handler.HandlerTuple(None)})

plt.xlabel('x')
plt.ylabel('$N$')

plt.show()

Изображение 174551

  • 0
    Спасибо за ваш ответ. Вчера я думал, что твой код работает. Вы внесли какие-либо изменения? Сегодня у меня эта ошибка при компиляции. "handler_map = {tuple: matplotlib.legend_handler.HandlerTuple (None)}) TypeError: __init __ () принимает 1 позиционный аргумент, но задано 2". Скажите, пожалуйста, в чем ошибка?
  • 0
    Я ничего не изменил (вы увидите, что ответ отредактирован так же, как вы увидели, что вы редактировали свой вопрос 16 часов назад). Вы запускали это в двух разных версиях matplotlib или python? HandlerTuple(ndivide=None) ли это при использовании HandlerTuple(ndivide=None) ?
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню