matplotlib에서 종횡비를 어떻게 설정할 수 있습니까?


108

정사각형 플롯 (imshow 사용), 즉 가로 세로 비율 1 : 1을 만들려고하는데 할 수 없습니다. 다음 중 어느 것도 작동하지 않습니다.

import matplotlib.pyplot as plt

ax = fig.add_subplot(111,aspect='equal')
ax = fig.add_subplot(111,aspect=1.0)
ax.set_aspect('equal')
plt.axes().set_aspect('equal')

호출이 무시되는 것 같습니다 (나는 종종 matplotlib에서 겪는 문제).


6
ax.axis('equal')우연히 시도 했습니까 ? 모두가 말했듯이, 당신이 한 일은 효과가 있지만 ax.axis해결 방법을 시도하는 또 다른 경로가 될 수 있습니다.
Joe Kington 2011

답변:


77

세 번째 매력. 내 생각 엔 이것이 버그이고 Zhenya의 대답 은 최신 버전에서 수정 되었음을 제안합니다. 버전 0.99.1.1이 있고 다음 솔루션을 만들었습니다.

import matplotlib.pyplot as plt
import numpy as np

def forceAspect(ax,aspect=1):
    im = ax.get_images()
    extent =  im[0].get_extent()
    ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect)

data = np.random.rand(10,20)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(data)
ax.set_xlabel('xlabel')
ax.set_aspect(2)
fig.savefig('equal.png')
ax.set_aspect('auto')
fig.savefig('auto.png')
forceAspect(ax,aspect=1)
fig.savefig('force.png')

이것은 'force.png'입니다. 여기에 이미지 설명 입력

아래는 실패했지만 유익한 시도입니다.

두 번째 답변 :

아래의 내 '원래 답변'은 과잉 axes.set_aspect()입니다. 나는 당신이 사용하고 싶다고 생각합니다 axes.set_aspect('auto'). 이것이 왜 그런지 이해하지 못하지만, 예를 들어 다음 스크립트와 같이 정사각형 이미지 플롯을 생성합니다.

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(10,20)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(data)
ax.set_aspect('equal')
fig.savefig('equal.png')
ax.set_aspect('auto')
fig.savefig('auto.png')

가로 세로 비율이 '동일'인 이미지 플롯 여기에 이미지 설명 입력 과 '자동'가로 세로 비율이 있는 이미지 플롯을 생성합니다 . 여기에 이미지 설명 입력

아래 '원래 답변'에 제공된 코드는 명시 적으로 제어되는 종횡비의 시작점을 제공하지만 imshow가 호출되면 무시되는 것 같습니다.

원래 답변 :

다음은 원하는 종횡비를 얻을 수 있도록 서브 플롯 매개 변수를 조정하는 루틴의 예입니다.

import matplotlib.pyplot as plt

def adjustFigAspect(fig,aspect=1):
    '''
    Adjust the subplot parameters so that the figure has the correct
    aspect ratio.
    '''
    xsize,ysize = fig.get_size_inches()
    minsize = min(xsize,ysize)
    xlim = .4*minsize/xsize
    ylim = .4*minsize/ysize
    if aspect < 1:
        xlim *= aspect
    else:
        ylim /= aspect
    fig.subplots_adjust(left=.5-xlim,
                        right=.5+xlim,
                        bottom=.5-ylim,
                        top=.5+ylim)

fig = plt.figure()
adjustFigAspect(fig,aspect=.5)
ax = fig.add_subplot(111)
ax.plot(range(10),range(10))

fig.savefig('axAspect.png')

이렇게하면 다음과 같은 그림이 생성됩니다. 여기에 이미지 설명 입력

그림에 여러 개의 서브 플롯이있는 경우 제공된 루틴에 y 및 x 서브 플롯의 수를 키워드 매개 변수 (기본값은 각각 1)로 포함하고 싶을 것입니다. 그런 다음 해당 숫자와 hspacewspace키워드를 사용하여 모든 서브 플롯이 올바른 종횡비를 갖도록 할 수 있습니다.


1
예를 들어 get_images빈 목록입니다 (같은 일어날 것입니다 ax.plot([0,1],[0,2]), 당신은 사용할 수 있습니다 get_xlimget_ylim
조엘

logscale을 사용하면 작동하지 않는 것 같습니다. 나는 그것을 테스트하고 처리하는 답변을 추가했습니다. 그것을 당신의 대답에 포함시켜 주시면 제가 제거하겠습니다.
Joel

1
측면이 같지 않은 이유는 같은 측면이 x의 시각적 거리가 y와 동일하다는 것을 의미하기 때문입니다. 이미지가 정사각형이지만 플롯 dx와 dy가 다르면 1 : 1 종횡비가 아닙니다. 이 경우 종횡비는 dy / dx가됩니다.
bart cubrich

22

matplotlib실행중인 버전 은 무엇입니까 ? 나는 최근에로 업그레이드해야 1.1.0했고 그것 add_subplot(111,aspect='equal')으로 나를 위해 일합니다.


1
matplotlib버전 에서 나를 위해 잘 작동합니다 2.0.2. jupyter notebook버전 5.0.0. 감사.
Sathish

5

위의 답변으로 수년 동안 성공한 후 다시 작동하지 않는 것으로 나타났습니다. 그러나 하위 그림에 대한 작업 솔루션을 찾았습니다.

https://jdhao.github.io/2017/06/03/change-aspect-ratio-in-mpl

물론 위의 저자 (아마도 여기에 게시 할 수있는 사람)에게 전적인 크레딧을 제공하면 관련 라인은 다음과 같습니다.

ratio = 1.0
xleft, xright = ax.get_xlim()
ybottom, ytop = ax.get_ylim()
ax.set_aspect(abs((xright-xleft)/(ybottom-ytop))*ratio)

링크에는 matplotlib에서 사용하는 다른 좌표계에 대한 명확한 설명도 있습니다.

모든 훌륭한 답변을 주셔서 감사합니다. 특히 승자가 될 @ Yann 's.


3

figaspect로 시도해야합니다. 그것은 나를 위해 작동합니다. 문서에서 :

지정된 종횡비로 Figure를 만듭니다. 경우 ARG는 다수 종횡비 즉 사용하는 것이다. > arg 가 배열이면 figaspect는 가로 세로 비율을 유지하면서 배열에 맞는 Figure의 너비와 높이를 결정합니다. 그림 너비, 높이 (인치)가 반환됩니다. 다음과 같이 및 높이가 같은 축을 만들어야합니다. 예 :

사용 예 :

  # make a figure twice as tall as it is wide
  w, h = figaspect(2.)
  fig = Figure(figsize=(w,h))
  ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
  ax.imshow(A, **kwargs)

  # make a figure with the proper aspect for an array
  A = rand(5,3)
  w, h = figaspect(A)
  fig = Figure(figsize=(w,h))
  ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
  ax.imshow(A, **kwargs)

편집 : 당신이 무엇을 찾고 있는지 잘 모르겠습니다. 위의 코드는 캔버스 (플롯 크기)를 변경합니다. 그림의 matplotlib 창의 크기를 변경하려면 다음을 사용하십시오.

In [68]: f = figure(figsize=(5,1))

이것은 5x1 (wxh)의 창을 생성합니다.


덕분에 캔버스의 가로 세로 비율을 변경하는 데 약간의 영향을 미칩니다.보다 구체적으로 그림 자체의 가로 세로 비율을 변경해야합니다. 다음 작업은 수행하지 않습니다 (apols 형식 지정 ..). = plt.figure (figsize = (plt.figaspect (2.0)))
jtlz2

3

이 답변은 Yann의 답변을 기반으로합니다. 선형 또는 로그-로그 플롯의 종횡비를 설정합니다. https://stackoverflow.com/a/16290035/2966723의 추가 정보를 사용 하여 축이 로그 스케일인지 테스트했습니다.

def forceAspect(ax,aspect=1):
    #aspect is width/height
    scale_str = ax.get_yaxis().get_scale()
    xmin,xmax = ax.get_xlim()
    ymin,ymax = ax.get_ylim()
    if scale_str=='linear':
        asp = abs((xmax-xmin)/(ymax-ymin))/aspect
    elif scale_str=='log':
        asp = abs((scipy.log(xmax)-scipy.log(xmin))/(scipy.log(ymax)-scipy.log(ymin)))/aspect
    ax.set_aspect(asp)

분명히 당신의 모든 버전 사용할 수 있습니다 log당신은 내가 사용했습니다 원하는을 scipy하지만, numpymath잘해야한다.

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