Сюжеты Matplotlib: удаление оси, легенды и пробелы - PullRequest
219 голосов
/ 15 февраля 2012

Я новичок в Python и Matplotlib, я хотел бы просто применить цветовую карту к изображению и написать результирующее изображение, без использования осей, меток, заголовков или чего-то, что обычно автоматически добавляется matplotlib.Вот что я сделал:

def make_image(inputname,outputname):
    data = mpimg.imread(inputname)[:,:,0]
    fig = plt.imshow(data)
    fig.set_cmap('hot')
    fig.axes.get_xaxis().set_visible(False)
    fig.axes.get_yaxis().set_visible(False)
    plt.savefig(outputname)

Он успешно удаляет ось фигуры, но сохраненная фигура представляет собой белые отступы и рамку вокруг фактического изображения.Как я могу удалить их (по крайней мере, белый отступ)?Спасибо

Ответы [ 9 ]

296 голосов
/ 15 февраля 2012

Я думаю, что команда axis('off') решает одну из проблем более кратко, чем изменение каждой оси и границы в отдельности. Это все еще оставляет белое пространство вокруг границы как бы то ни было. Добавление bbox_inches='tight' к команде savefig почти приведет вас туда. В приведенном ниже примере видно, что оставшееся пустое пространство намного меньше, но все еще присутствует.

Обратите внимание, что в новых версиях matplotlib может потребоваться bbox_inches=0 вместо строки 'tight' (через @episodeyang и @kadrach)

from numpy import random
import matplotlib.pyplot as plt

data = random.random((5,5))
img = plt.imshow(data, interpolation='nearest')
img.set_cmap('hot')
plt.axis('off')
plt.savefig("test.png", bbox_inches='tight')

enter image description here

89 голосов
/ 15 февраля 2012

Я узнал этот трюк от matehat, здесь :

import matplotlib.pyplot as plt
import numpy as np

def make_image(data, outputname, size=(1, 1), dpi=80):
    fig = plt.figure()
    fig.set_size_inches(size)
    ax = plt.Axes(fig, [0., 0., 1., 1.])
    ax.set_axis_off()
    fig.add_axes(ax)
    plt.set_cmap('hot')
    ax.imshow(data, aspect='equal')
    plt.savefig(outputname, dpi=dpi)

# data = mpimg.imread(inputname)[:,:,0]
data = np.arange(1,10).reshape((3, 3))

make_image(data, '/tmp/out.png')

дает

enter image description here

43 голосов
/ 28 октября 2014

Возможное простейшее решение:

Я просто объединил метод, описанный в вопросе, и метод из ответа Hooked.

fig = plt.imshow(my_data)
plt.axis('off')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('pict.png', bbox_inches='tight', pad_inches = 0)

После этого кода нет пробелов и фрейма.

No whitespaces, axes or frame

24 голосов
/ 20 июля 2017

Никто не упомянул imsave, что делает его однострочным:

import matplotlib.pyplot as plt
import numpy as np

data = np.arange(10000).reshape((100, 100))
plt.imsave("/tmp/foo.png", data, format="png", cmap="hot")

Он непосредственно сохраняет изображение как есть, то есть не добавляет никаких осей или границ / отступов.

enter image description here

8 голосов
/ 29 августа 2014

Вы также можете указать экстент фигуры для аргумента bbox_inches. Это избавило бы от белого отступа вокруг фигуры.

def make_image(inputname,outputname):
    data = mpimg.imread(inputname)[:,:,0]
    fig = plt.imshow(data)
    fig.set_cmap('hot')
    ax = fig.gca()
    ax.set_axis_off()
    ax.autoscale(False)
    extent = ax.get_window_extent().transformed(plt.gcf().dpi_scale_trans.inverted())
    plt.savefig(outputname, bbox_inches=extent)
5 голосов
/ 28 июля 2018

Это должно удалить все отступы и границы:

from matplotlib import pyplot as plt

fig = plt.figure()
fig.patch.set_visible(False)

ax = fig.add_subplot(111)

plt.axis('off')
plt.imshow(data)

extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig("../images/test.png", bbox_inches=extent)
2 голосов
/ 09 марта 2018

Мне понравился ответ в Ubuntu, но он не показывал явно, как установить размер для неквадратных изображений из коробки, поэтому я изменил его для легкой копирования-вставки:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

def save_image_fix_dpi(data, dpi=100):
    shape=np.shape(data)[0:2][::-1]
    size = [float(i)/dpi for i in shape]

    fig = plt.figure()
    fig.set_size_inches(size)
    ax = plt.Axes(fig,[0,0,1,1])
    ax.set_axis_off()
    fig.add_axes(ax)
    ax.imshow(data)
    fig.savefig('out.png', dpi=dpi)
    plt.show()

Сохранять изображения без рамки легко, независимо от того, какое значение dpi вы выберете, если сохранить pixel_size / dpi = size.

data = mpimg.imread('test.png')
save_image_fix_dpi(data, dpi=100)

enter image description here

Однако отображение выглядит жутко. Если вы выберете маленькое dpi, размер вашего изображения может быть больше, чем у экрана, и вы получите границы во время отображения. Тем не менее, это не влияет на сохранение.

Так что для

save_image_fix_dpi(data, dpi=20)

Дисплей становится окаймленным (но сохранение работает): enter image description here

1 голос
/ 28 декабря 2017

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

Для сохранения фактического *Изображение 1005 *, которое может быть полезно для добавления аннотаций или других данных к изображениям, я использовал следующее решение:

fig, ax = plt.subplots(figsize=inches)
ax.matshow(data)  # or you can use also imshow
# add annotations or anything else
# The code below essentially moves your plot so that the upper
# left hand corner coincides with the upper left hand corner
# of the artist
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
# now generate a Bbox instance that is the same size as your
# single axis size (this bbox will only encompass your figure)
bbox = matplotlib.transforms.Bbox(((0, 0), inches))
# now you can save only the part of the figure with data
fig.savefig(savename, bbox_inches=bbox, **kwargs)
0 голосов
/ 08 мая 2019

Ответ с лишним голосом больше не работает.Чтобы заставить его работать, вам нужно вручную добавить ось, установленную в [0, 0, 1, 1], или удалить патч под рисунком.

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(5, 5), dpi=20)
ax = plt.Axes(fig, [0., 0., 1., 1.])
fig.add_axes(ax)
plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')                                # same as: ax.set_axis_off()

plt.savefig("test.png")

В качестве альтернативы, вы можете просто удалить патч.Вам не нужно добавлять подзаговор, чтобы удалить отступы.Это упрощено от ответа Влады ниже

fig = plt.figure(figsize=(5, 5))
fig.patch.set_visible(False)                   # turn off the patch

plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')

plt.savefig("test.png", cmap='hot')

Это проверено с версией 3.0.3 2019/06/19.Изображение см. Ниже:

enter image description here

Намного проще использовать pyplot.imsave.Подробнее см. Ответ Луатора ниже

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