get_legend_handle_labels() не возвращает новые данные легенды

#matplotlib

#python #matplotlib

Вопрос:

Это сводит меня с ума. Я создаю небольшую настраиваемую функцию легенды, в которую вы добавляете некоторый текст и свойства, и она сделает это за вас. Итак, прежде чем это станет доступным в графическом интерфейсе, к этому моменту уже была создана фигура с легендой, в которой есть «run5» и «run6».

Я написал что-то, что удаляет существующую легенду и снова вызывает легенду на той же оси с новыми дескрипторами / метками. Однако, когда я сразу после этого выполняю ax.get_legend_handle_labels(), он возвращает дескриптор и метки удаленной легенды, полностью игнорируя вызов легенды, который я только что сделал.

Я попытался удалить легенду, а затем просто воссоздать ее. Но очевидно, что ax сохраняет данные предыдущей легенды.

 from matplotlib.lines import Line2D

ax = self.axes[ind] #just the axis handle
custom_lines, custom_strings = [], []        
try:
    ax.get_legend().remove()
except:
    # Means no legend exists
    pass
for idx, i in enumerate(self.lgndRowWidget):
    if not i.isHidden():
        #The below five lines are grabbing data from GUI
        lineText  = self.lgndStr[idx].text() # Is "test" here
        lineType  = self.lgndLine[idx].currentText()
        lineWidth = self.lgndWidth[idx].value()
        lineMrkr  = self.lgndMrkr[idx].currentText()
        lineClr   = self.lgndClr[idx].text()

        custom_lines.append(Line2D([0],[0],
                            lw=lineWidth,
                            ls=lineType,
                            marker=lineMrkr,
                            color=lineClr))                                           
        custom_strings.append(lineText)

if len(custom_lines) != 0:
    print(custom_strings)
    self.legList = ax.legend(custom_lines, custom_strings)
    a,b = ax.get_legend_handles_labels()
    print(b)
    self.fig.canvas.draw()
  

print(custom_strings) возвращает все, что я ввожу. В данном случае «тест».
print(b) возвращает то, что было ранее в легенде, от которой я, похоже, не могу избавиться: начальные «run5» и «run6». Это ДОЛЖНО быть «test».

Ответ №1:

Возможно, вы неправильно поняли функциональность ax.get_legend_handles_labels() .

Что он делает, так это ищет исполнителей (например, строки, коллекции и т.д.), У которых есть метка. Затем он возвращает этих исполнителей и их соответствующие метки. Следовательно ax.legend() , примерно эквивалентно

 handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles, labels=labels)
  

.get_legend_handles_labels() не знает, присутствует ли легенда, потому что она возвращает то, что должно быть в легенде, а не то, что в ней есть в данный момент.

Комментарии:

1. Это … имеет гораздо больше смысла, спасибо. Итак, я предполагаю, что, поскольку get_legend_handle_labels не возвращает две строки Line2D, с помощью которых я создал новую легенду, значит, они на самом деле не существуют? Есть ли способ получить свойства и имена этих строк?

2. Да, но поскольку вы их создали, вы все равно должны знать строки и их имена.

3. @ImportanceOfBeingErnest есть ли какой-нибудь способ получить новые данные легенды? Мне нужно вызвать что-то вроде fig.legend(*ax.get_legend_handles_labels()) перемещения общей легенды из подзаголовков в рисунок, и я не хочу вручную вводить измененные метки, потому что они поступают из другой функции.

4. Легенда имеет атрибуты .legendHandles , .texts которые позволили бы извлечь все из существующей легенды. Еще раз я хотел бы подчеркнуть, что если вы вручную добавите что-то в легенду, вы уже знаете , что вы вставили, и можете просто использовать это.