Matplotlib 플롯 : 축, 범례 및 공백 제거


285

저는 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)

그림의 축을 성공적으로 제거하지만 저장된 그림은 실제 이미지 주위에 흰색 패딩과 프레임을 나타냅니다. 어떻게 제거 할 수 있습니까 (적어도 흰색 패딩)? 감사


2
이 질문에 대한 모든 솔루션에 중점을 둡니다 imshow. 당신이 산점도가있는 경우 대신 다음 대답은 당신을 도울 수 있습니다 stackoverflow.com/a/40727744/4124317
ImportanceOfBeingErnest

답변:


373

이 명령 axis('off')은 각 축과 경계를 개별적으로 변경하는 것보다 간결하게 문제 중 하나를 처리 한다고 생각합니다 . 그러나 여전히 테두리 주위에 공백이 남습니다. 추가 bbox_inches='tight'받는 savefig공백 왼쪽이 훨씬 작은,하지만 여전히 존재 그 아래 명령하는 것은 거의 당신을 얻을, 당신은 예를 볼 수 있습니다.

matplotlib의 최신 버전은 @episodeyang 및 @kadrach를 통해 bbox_inches=0문자열 대신 필요할 수 있습니다.'tight'

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')

여기에 이미지 설명을 입력하십시오


4
unutbu의 제안에 따라, 당신은 사용할 수 있습니다 fig = plt.figure(), ax = plt.axes([0,0,1,1])다음, plt.imshow(data,interpolation="nearest". 와 결합 plt.axis("off")하면 이미지 자체 이외의 모든 것을 제거해야합니다.
PhilMacKay

5
질문의 메소드를 결합하면 ({fig.axes.get_xaxis (). set_visible (False) & fig.axes.get_yaxis (). set_visible (False)}와 {plt.axis ( 'off')}) 문제가 해결되었습니다. 나를. (더 이상 공백은 없습니다). savefig에서 {pad_inches}를 0으로 설정하는 것을 잊지 마십시오.
Domagoj

3
방금이 문제를 가로 질러이 스레드의 솔루션 중 하나도 연결되지 않았습니다. 그러나 명시 적으로 지정 bbox_inches=0하면 트릭이되었습니다.
kadrach

1
plt.plot (x, y)에서와 같이 plt.imshow 위에 물건을 '플로팅'하는 경우 xlim과 ylim을 행렬의 크기로 설정해야합니다.
Mathusalem

1
이것은 더 이상 작동하지 않습니다. 알아 내기 위해 한 시간 걸렸습니다. 아래 답변을 참조하십시오.
episodeyang

107

나는 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')

수확량

여기에 이미지 설명을 입력하십시오


3
나는 당신이 정답을 가지고 있다고 확신합니다 (아마도 하나 이상의 방법이 있지만) 정답 인지 설명 할 수 있는지 궁금합니다 . 공백을 제거하는 코드는 어떻습니까?
Yann

4
@Yann은 문서 외에도 각 명령이 어떤 영향을 미치는지 확인하기 위해 한 번에 한 줄씩 주석 처리하는 것이 매우 유용합니다. 실험적인 방법입니다!
unutbu

4
흰색 테두리를 제거하는 선은 plt.Axes(fig, [0,0,1,1])입니다. 이것은 matplotlib에게 (0 %, 0 %)에 위치한 지점에서 왼쪽 하단 모서리와 너비와 높이가 (100 %, 100 %) 인 축 세트를 작성하도록 지시합니다.
PhilMacKay

저장된 이미지의 공백을 제거 할뿐만 아니라 화면상의 플롯도 제거하므로보다 정답입니다.
MaxNoe

감사합니다,이 유일한 해결책 : 내 우분투에서 잘 작동입니다
AlphaGoMK

56

가능한 가장 간단한 해결책 :

나는 단순히 질문에 설명 된 방법과 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)

이 코드 다음에는 공백과 프레임이 없습니다.

공백, 축 또는 프레임이 없음


3
귀하의 방법 으로이 이미지 주위의 모든 공백을 제거했지만 잘 작동했지만 여전히 명령을 추가 fig.axes.get_xaxis().set_visible(False)하여 문제를 해결하는 이유를 모르겠습니다 . 감사합니다
ollydbg23

5
이 명령을 호출하지 않으면 대부분의 공백이 제거됩니다. 그러나 필자의 경우 플롯과 .png 이미지의 가장자리 사이에 약간의 공백이 여전히 있습니다 (폭 2px). 다음 명령을 호출하여 완고한 공간을 제거했습니다.
Domagoj

3
그러나 위의 그림은 동일한 그림 (여기서는 플롯에 포함 된 이미지)에 여러 축이있는 경우 실패합니다. 솔루션 : fig.axes[0], 일반적으로 모든 또는 선택된 축.
Ioannis Filippidis 2016

29

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")

이미지를 그대로 저장합니다. 즉, 축이나 테두리 / 패딩을 추가하지 않습니다.

여기에 이미지 설명을 입력하십시오


이것이 내가 대부분하는 일이지만, 컬러 바가 필요할 때가 있는데,이 경우 imsave는 저를 구할 수 없습니다.
Elias

9

또한 그림의 범위를 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)

8

패딩과 테두리를 모두 제거해야합니다.

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)

과소 평가! 이것은 나에게 99 %의 길을 얻었습니다. 최신 버전이므로 더 많이지지를 받아야합니다
Nathan

ax와 함께 Axes 객체 ( ) 가없는 경우에도 작동합니다 extent = plt.gca().get_window_extent().transformed(fig.dpi_scale_trans.inverted()).
토스트


3

공감 된 답변은 더 이상 작동하지 않습니다. 작동하게하려면 축을 수동으로 [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")

또는 패치를 제거 할 수도 있습니다. 패딩을 제거하기 위해 서브 플롯을 추가 할 필요가 없습니다. 이것은 아래 Vlady의 답변 에서 단순화되었습니다.

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.32019/06/19 버전 으로 테스트되었습니다 . 이미지 아래 참조 :

여기에 이미지 설명을 입력하십시오

훨씬 간단한 방법은 사용하는 것 pyplot.imsave입니다. 자세한 내용 은 루터의 답변을 참조하십시오.


나를 위해 Axes 버전 만 작동합니다. 패치가 꺼진 버전으로 패딩이 발생합니다. 어쨌든 thx!
save_jeff

2

우분투의 대답이 마음 에 들었지만 사각형이 아닌 이미지의 크기를 즉시 설정하는 방법을 명시 적으로 표시하지 않았으므로 쉽게 복사하여 붙여 넣을 수 있도록 수정했습니다.

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()

pixel_size / dpi = size를 유지하면 선택한 dpi를 경계없이 이미지를 쉽게 저장할 수 있습니다.

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

여기에 이미지 설명을 입력하십시오

그러나 표시가 짜증납니다. 작은 dpi를 선택하면 이미지 크기가 화면보다 커질 수 있으며 표시 중에 테두리가 생깁니다. 그럼에도 불구하고 이것은 절약에 영향을 미치지 않습니다.

그래서

save_image_fix_dpi(data, dpi=20)

디스플레이가 경계가됩니다 (그러나 저장 작업). 여기에 이미지 설명을 입력하십시오


1

첫째, 특정 이미지 형식 (예 : TIFF) )의 경우 실제로 컬러 맵을 헤더에 저장할 수 있으며 대부분의 뷰어는 데이터를 컬러 맵과 함께 표시합니다.

matplotlib주석 또는 기타 데이터를 이미지에 추가하는 데 유용한 실제 이미지 를 저장 하기 위해 다음 솔루션을 사용했습니다.

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

모두의 멋진 답변에 감사드립니다 ... 추가 패딩 / 공간 등이없는 이미지 만 플롯하려는 것과 정확히 같은 문제가 있었으므로 여기에서 모든 사람의 아이디어를 찾는 것이 매우 기뻤습니다.

패딩이없는 이미지 외에도 간단한 이미지 플롯 외에도 주석 등을 쉽게 추가 할 수 있기를 원했습니다.

그래서 내가 한 일은 David의 대답csnemes ' 를 결합 하여 그림을 만들 때 간단한 래퍼를 만드는 것입니다. 그것을 사용할 때 나중에 imsave () 또는 다른 것을 사용하여 변경할 필요가 없습니다.

def get_img_figure(image, dpi):
    """
    Create a matplotlib (figure,axes) for an image (numpy array) setup so that
        a) axes will span the entire figure (when saved no whitespace)
        b) when saved the figure will have the same x/y resolution as the array, 
           with the dpi value you pass in.

    Arguments:
        image -- numpy 2d array
        dpi -- dpi value that the figure should use

    Returns: (figure, ax) tuple from plt.subplots
    """

    # get required figure size in inches (reversed row/column order)
    inches = image.shape[1]/dpi, image.shape[0]/dpi

    # make figure with that size and a single axes
    fig, ax = plt.subplots(figsize=inches, dpi=dpi)

    # move axes to span entire figure area
    fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)

    return fig, ax
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.