#image #matplotlib
#изображение #matplotlib
Вопрос:
Мне нужно добавить фигуру к уже существующему изображению, сгенерированному с помощью pyplot (plt). Лучший известный мне способ быстрого создания базовых фигур — это использование предопределенных фигур Imagedraw. Исходные данные содержат точки с соответствующими цветами в line_holder и colorholder. Мне нужно добавить ограничивающую рамку (или, в данном случае, эллипс) к графику, чтобы пользователю было очевидно, находятся ли данные в допустимом диапазоне.
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from PIL import Image
...
lines = LineCollection(mpl.line_holder, colors=mpl.colorholder , linestyle='solid')
plt.axes().add_collection(lines)
plt.axes().set_aspect('equal', 'datalim')
plt.axes().autoscale_view(True,True,True)
plt.draw()
plt.show()
Я пытался вставить это перед show ():
image = Image.new('1',(int(ceil(disc/conv)) 2,int(ceil(disc/conv)) 1), 1)
draw = ImageDraw.Draw(image)
box=(1, 1, int(ceil(disc/conv)), int(ceil(disc/conv))) #create bounding box
draw.ellipse(box, 1, 0) #draw circle in black
но я не могу найти способ добавить этот эллипс в pyplot. Кто-нибудь знает, как можно было бы объединить изображения? Если невозможно добавить объект imagedraw в pyplot, существуют ли хорошие альтернативы для выполнения этого типа операции?
Комментарии:
1. Можете ли вы опубликовать свой импорт? Было бы неплохо посмотреть, откуда все берется.
Ответ №1:
В Matplotlib есть несколько исправлений (фигур), которые, по-видимому, соответствуют вашим потребностям (и удаляют PIL как зависимость). Они задокументированы здесь. Здесь приведен полезный пример использования фигур.
Чтобы добавить эллипс к графику, вы сначала создаете участок эллипса, а затем добавляете этот участок к осям, над которыми вы в данный момент работаете. Будьте осторожны, что окружность (или эллипс с равными меньшими радиусами) будут выглядеть эллиптическими, если ваше соотношение сторон не равно.
В вашем фрагменте вы вызываете plt.axes() несколько раз. В этом нет необходимости, поскольку он просто возвращает текущий объект axes. Я думаю, что понятнее сохранить объект axes и напрямую работать с ним, а не повторно получать один и тот же объект через plt.axes (). Поскольку axes () используется в вашем фрагменте, gca () делает то же самое. Конец моего скрипта демонстрирует это.
Я также заменил вашу строку add_collection () на построение одной строки. Они, по сути, делают то же самое и позволяют выполнять мой фрагмент как отдельный скрипт.
import matplotlib.pyplot as plt
import matplotlib as mpl
# set up your axes object
ax = plt.axes()
ax.set_aspect('equal', 'datalim')
ax.autoscale_view(True, True, True)
# adding a LineCollection is equivalent to plotting a line
# this will run as a stand alone script
x = range(10)
plt.plot( x, x, 'x-')
# add and ellipse to the axes
c = mpl.patches.Ellipse( (5, 5), 1, 6, angle=45)
ax.add_patch(c)
# you can get the current axes a few ways
ax2 = plt.axes()
c2 = mpl.patches.Ellipse( (7, 7), 1, 6, angle=-45, color='green')
ax2.add_patch(c2)
ax3 = plt.gca()
c3 = mpl.patches.Ellipse( (0, 2), 3, 3, color='black')
ax3.add_patch(c3)
print id(ax), id(ax2), id(ax3)
plt.show()
Комментарии:
1. plt не является pylab. Моя ошибка, я не включил импорт выше. Теперь я добавил их.
2. что касается axes (), draw() и plot (), то pylab и matplotlib.pyplot одинаковы. я обновил свой фрагмент, чтобы использовать mpl.pyplot просто для наглядности.
3. Это работает не совсем так, как написано. Исправления должны быть необязательной функцией, которая будет добавлена позже. Используя приведенный выше код в качестве примера, show() вызывается сразу после plt.plot() , и затем исправления должны быть помещены на график, который генерируется, если пользователь запрашивает их.
4. также границы графика должны сместиться, чтобы патч был полностью виден.
5. чтобы изменить график после его визуализации, вам нужно будет добавить функцию обратного вызова для выполнения модификации ( matplotlib.sourceforge.net/users/event_handling.html ). Не забудьте выполнить повторный рендеринг с помощью fig.canvas.draw()