Участок к изображению объекта - PullRequest
1 голос
/ 28 марта 2020

Я могу сохранить один график с помощью imshow(), поскольку он возвращает объект изображения, например:

image = plt.imshow(list, interpolation=None)

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

anim = animation.ArtistAnimation(fig, images, interval=15, blit=True)

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

list = [[1,2,3,4,5,6,7,8],
        [1,2,3,4,5,6,7,8]]
list2 = [[1,2,3,4,5,6,7,8],
        [1,2,3,4,5,6,7,8]]

fig = plt.figure()

ax = fig.add_subplot(2, 1, 1)
ax.imshow(list, interpolation=None)

ax2 = fig.add_subplot(2, 1, 2)
ax2.imshow(list, interpolation=None)

plt.show()

Вместо того, чтобы показывать график, я хочу сохранить его как объект изображения. Моя цель - создать анимацию (из множества сюжетов) и визуализировать ее как видео. Может быть, мой подход неверен. Есть ли лучшее решение?

Ответы [ 4 ]

1 голос
/ 28 марта 2020

вы можете использовать:

plt.savefig('name.png')
0 голосов
/ 28 марта 2020

Вот адаптация этого примера для работы с двумя списками данных. Обратите внимание, что когда у всех изображений не одинаковый диапазон данных, этот диапазон будет взят из первого нарисованного элемента. Обходной путь должен явно установить vmin и vmax к глобальному минимуму и максимуму.

from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np

x, y = np.meshgrid(np.linspace(0, 5, 30), np.linspace(0, 5, 10))
list1 = [np.sin(x + i * 0.10) * np.cos(y + i * 0.01) for i in range(50)]
list2 = [np.cos(x + i * 0.01) * np.sin(y + i * 0.10) for i in range(50)]
list1[0] = np.zeros_like(list1[0])  # test what happens when the first element has only one color

fig = plt.figure()

ax1 = fig.add_subplot(2, 1, 1)

vmin1 = min([l.min() for l in list1 ])
vmin2 = min([l.min() for l in list2 ])
vmax1 = max([l.max() for l in list1 ])
vmax2 = max([l.max() for l in list2 ])
ax2 = fig.add_subplot(2, 1, 2)
im1 = ax1.imshow(list1[0], interpolation=None, animated=True, vmin=vmin1, vmax=vmax1)
im2 = ax2.imshow(list2[0], interpolation=None, animated=True, cmap='inferno', vmin=vmin2, vmax=vmax2)

def updatefig(i):
    im1.set_array(list1[i])
    im2.set_array(list2[i])
    return im1, im2,

ani = animation.FuncAnimation(fig, updatefig, frames=len(list1), interval=20, blit=True)
plt.show()
0 голосов
/ 28 марта 2020

Вы можете сохранить его в "в памяти" буфере, например так:

# Save PNG to memory buffer as BytesIO
from io import BytesIO
buffer = BytesIO()

plt.savefig(buffer,format='png')
PNG = buffer.getvalue()

Если вы хотите, чтобы вам понадобилось изображение PIL / Pillow из этого:

reloadedPILImage = Image.open(buffer)
0 голосов
/ 28 марта 2020
plt.savefig('someimgname.jpg')

Это поможет. Но помните, после того, как вы это сделаете - откройте это с помощью Image.Open(), и это сработает.

im  = Image.open('someimgname.jpg')
im.show() # or do whatever you want to do with this image object

Пример кода:

from matplotlib import pyplot as plt
from PIL import Image

list = [[1,2,3,4,5,6,7,8],
        [1,2,3,4,5,6,7,8]]
list2 = [[1,2,3,4,5,6,7,8],
        [1,2,3,4,5,6,7,8]]

fig = plt.figure()

ax = fig.add_subplot(2, 1, 1)
ax.imshow(list, interpolation=None)

ax2 = fig.add_subplot(2, 1, 2)
ax2.imshow(list, interpolation=None)
plt.savefig('someimgname.jpg')
im = Image.open("someimgname.jpg")  # desired image object
im.show()
plt.show()

Ссылки:

  1. Ссылка на подушку
  2. Ссылка на Matplotlib

Хорошо для второй части ответа, пока я проверял do c для matplotlib.pyplot.savefig(*args, **kwargs) сказано.

Первый аргумент fname - это A path, or a Python file-like object, or possibly some backend-dependent object such as.

В python объект типа файла - StringIO объектов.

buf = io.BytesIO()
plt.savefig(buf, format='jpg')
buf.seek(0)
im = Image.open(buf)

Из документации python это стало еще более логичным: -

Потоки в памяти: также можно использовать объект типа str или байтов в качестве файл для чтения и записи. Для строк StringIO может использоваться как файл, открытый в текстовом режиме. BytesIO можно использовать как файл, открытый в двоичном режиме. Оба предоставляют полные возможности чтения-записи с произвольным доступом.

Пример кода: ( В памяти )

from matplotlib import pyplot as plt
from PIL import Image
import io

list = [[1,2,3,4,5,6,7,8],
        [1,2,3,4,5,6,7,8]]
list2 = [[1,2,3,4,5,6,7,8],
        [1,2,3,4,5,6,7,8]]

fig = plt.figure()

ax = fig.add_subplot(2, 1, 1)
ax.imshow(list, interpolation=None)

ax2 = fig.add_subplot(2, 1, 2)
ax2.imshow(list, interpolation=None)
plt.show()
buf = io.BytesIO()
plt.savefig(buf, format='jpg')
buf.seek(0)
im = Image.open(buf)
im.show()

Ссылка: 3. Python документов

...