Значение Matplotlib для изображения в виде массива numpy

Я пытаюсь получить изображение массива numpy из фигуры Matplotlib, и в настоящее время я делаю это, сохраняя файл, а затем снова читаю файл, но я чувствую, что должен быть лучший способ. Вот что я делаю сейчас:

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.gca()

ax.text(0.0,0.0,"Test", fontsize=45)
ax.axis('off')

canvas.print_figure("output.png")
image = plt.imread("output.png")

Я пробовал это:

image = np.fromstring( canvas.tostring_rgb(), dtype='uint8' )

из примера, который я нашел, но он дает мне ошибку, говоря, что объект 'FigureCanvasAgg' не имеет атрибута 'renderer'.

Ответ 1

Чтобы получить содержимое фигуры в качестве значений пикселя RGB, matplotlib.backend_bases.Renderer нужно сначала нарисовать содержимое холста. Вы можете сделать это, вызвав вручную canvas.draw():

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.gca()

ax.text(0.0,0.0,"Test", fontsize=45)
ax.axis('off')

canvas.draw()       # draw the canvas, cache the renderer

image = np.fromstring(canvas.tostring_rgb(), dtype='uint8')

См. здесь для получения дополнительной информации о API matplotlib.

Ответ 2

из документов:

https://matplotlib.org/gallery/user_interfaces/canvasagg.html#sphx-glr-gallery-user-interfaces-canvasagg-py

fig = Figure(figsize=(5, 4), dpi=100)
# A canvas must be manually attached to the figure (pyplot would automatically
# do it).  This is done by instantiating the canvas with the figure as
# argument.
canvas = FigureCanvasAgg(fig)

# your plotting here

canvas.draw()
s, (width, height) = canvas.print_to_buffer()

# Option 2a: Convert to a NumPy array.
X = np.fromstring(s, np.uint8).reshape((height, width, 4))

Ответ 3

Для людей, которые ищут ответ на этот вопрос, это код, полученный из предыдущих ответов. Имейте в виду, что метод np.fromstring устарел и вместо него используется np.frombuffer.

#Image from plot
ax.axis('off')
fig.tight_layout(pad=0)
fig.canvas.draw()
image_from_plot = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
image_from_plot = image_from_plot.reshape(fig.canvas.get_width_height()[::-1] + (3,))

Проблема изображений, имеющих огромные белые границы, все еще остается, хотя и с использованием fig.tight_layout(pad=0).