Как изменить легенду matplotlib после ее создания?
у меня есть доступ к экземпляру figure fig = pylab.gcf()
. Я знаю, что на этом рисунке есть легенда, и я могу получить к ней доступ через myLegend = fig.gca().legend_
. Теперь я хочу изменить свойства легенды. Некоторые из них у меня есть доступ через сеттеры, такие как myLegend.set_frame_on(True)
.
при создании легенды она принимает ряд аргументов ключевого слова:
класс библиотек matplotlib.легенда.Легенда (родитель, дескрипторы, метки, loc=нет, numpoints=нет, markerscale=нет, scatterpoints=нет, scatteryoffsets=нет, prop=нет, fontsize=нет, borderpad=нет, labelspacing=нет, handlelength=нет, handleheight=нет, handletextpad=нет, borderaxespad=нет, свойства columnspacing=нет, номер колонки=1, mode=нет, fancybox=нет, shadow=нет, title=нет, framealpha=нет, bbox_to_anchor=нет, bbox_transform=нет, frameon=нет, handler_map=нет)
как я могу изменить все аргументы ключевого слова в легенде после легенда?
один из проблемные из них numpoints
(количество маркеров в легенде, по умолчанию-2). Ниже приведен пример того, как я хочу его изменить:
это показывает, как я хочу, чтобы программы
import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(loc = "lower left")
# no modifications above this line
setattr(pylab.gcf().gca().legend_, 'numpoints',1)
pylab.show()
это показывает, как я хочу, чтобы это выглядело как
import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(numpoints = 1, loc = "lower left")
pylab.show()
Я проверил исходный код, есть переменная numpoint, которая изменяется, но верхний регистр не обновляется до экрана. Что я упускаю?
4 ответов
я написал функцию modify_legend
который изменяет легенду после ее создания. Он в основном считывает все параметры из уже созданной легенды, обновляет ее с параметрами ключа-значения, которые вы предоставили, и вызывает legend(...)
опять со всеми возможными параметрами.
import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(loc = "lower left")
modify_legend(numpoints = 1)
pylab.show()
здесь код modify_legend
:
def modify_legend(**kwargs):
import matplotlib as mpl
l = mpl.pyplot.gca().legend_
defaults = dict(
loc = l._loc,
numpoints = l.numpoints,
markerscale = l.markerscale,
scatterpoints = l.scatterpoints,
scatteryoffsets = l._scatteryoffsets,
prop = l.prop,
# fontsize = None,
borderpad = l.borderpad,
labelspacing = l.labelspacing,
handlelength = l.handlelength,
handleheight = l.handleheight,
handletextpad = l.handletextpad,
borderaxespad = l.borderaxespad,
columnspacing = l.columnspacing,
ncol = l._ncol,
mode = l._mode,
fancybox = type(l.legendPatch.get_boxstyle())==mpl.patches.BoxStyle.Round,
shadow = l.shadow,
title = l.get_title().get_text() if l._legend_title_box.get_visible() else None,
framealpha = l.get_frame().get_alpha(),
bbox_to_anchor = l.get_bbox_to_anchor()._bbox,
bbox_transform = l.get_bbox_to_anchor()._transform,
frameon = l._drawFrame,
handler_map = l._custom_handler_map,
)
if "fontsize" in kwargs and "prop" not in kwargs:
defaults["prop"].set_size(kwargs["fontsize"])
mpl.pyplot.legend(**dict(defaults.items() + kwargs.items()))
примечания по коду:
- некоторые параметры могли легко Читайте из
Вы можете использовать команду pylab.legend
снова с правильными ключевыми словами / аргументами. Это изменит существующую легенду вместо создания новой. Ниже вы найдете свой пример, слегка измененный.
import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(loc = "lower left")
# Change the number of markers shown in the legend
pylab.legend(numpoints = 1, loc = "lower left")
pylab.show()
надеюсь, что это помогает.
то, что вы видите в легенде, на самом деле это Line2D
. Изменение numpoints
после того, как эта строка была создана, не будет обновлять указанную строку, поэтому вам придется получить дескриптор на Line2D
"объект" и удалить одну из точек вручную:
import pylab
pylab.plot(0,0,'ro', label = 'one point')
legend = pylab.legend(loc = "lower left")
markers = legend.get_children()[0].get_children()[1].get_children()[0].get_children()[0].get_children()[0].get_children()[1]
markers.set_data(map(pylab.mean, markers.get_data()))
pylab.show()
на get_children()
цепь требуется, потому что matplotlib обертывает линию в несколько слоев горизонтальных и вертикальных пакетов. Приведенного выше фрагмента должно быть достаточно, чтобы дать вам общее представление, но в реальном приложении предпочтительный способ получить ручка будет следовать подсказка легенды руководства по legend handlers и использовать индивидуальные HandlerLine2D
это хранит линию в некотором роде.
если бы это был я, я бы поместил его в другой текстовый файл, чтобы сделать это, так как это будет легче изменить и отслеживать, особенно если у вас есть много кода до и после этого.
чтобы открыть файл для записи, мы устанавливаем второй параметр на " w "вместо"r".(of fobj = open("ad_lesbiam.txt", "r")
) чтобы фактически записать данные в этот файл, мы используем метод write() объекта дескриптора файла.
давайте начнем с очень простого и понятного примера:
fh = open("example.txt", "w")
fh.write("To write or not to write\nthat is the question!\n")
fh.close()
особенно если вы пишете в файл, вы никогда не должны забывать закрыть дескриптор файла снова. В противном случае вы рискуете оказаться в несогласованном состоянии ваших данных.
вы часто найдете оператор with для чтения и записи файлов. Преимущество заключается в том, что файл будет автоматически закрыт после отступа блока после завершения выполнения with:
with open("example.txt", "w") as fh:
fh.write("To write or not to write\nthat is the question!\n")
наш первый пример также может быть переписан следующим образом: с заявлением:
with open("ad_lesbiam.txt") as fobj:
for line in fobj:
print(line.rstrip())
пример для одновременного чтения и записи:
fobj_in = open("ad_lesbiam.txt")
fobj_out = open("ad_lesbiam2.txt","w")
i = 1
for line in fobj_in:
print(line.rstrip())
fobj_out.write(str(i) + ": " + line)
i = i + 1
fobj_in.close()
fobj_out.close()
к твоему сведению. Каждая строка входного текстового файла имеет префикс по номеру строки