Подтвердить что ты не робот

Matplotlib - подзаголовки с фиксированным соотношением сторон

У меня проблема с построением нескольких подзаговоров. Я хотел бы установить ФИЗИЧЕСКОЕ соотношение сторон подзаголовков на фиксированное значение. В моем примере у меня 12 подзаголовков (4 строки и 3 столбца) на альбомной фигуре A4. Там все подсечки хорошо расположены на всей фигуре, а для всех подсетей высота почти равна ширине.

Но если я изменил макет моей фигуры на портрет, подзаголовки растягиваются вертикально. И это точно, что не должно произойти. Я хотел бы иметь такую ​​же высоту и ширину подзаголовков, что и на пейзажной фигуре. Существует ли вероятность того, что соотношение сторон в подзаголовках останется неизменным?

Спасибо заранее, Питер

EDIT: Я нашел обходное решение. Но это работает только для не логарифмических осей...

aspectratio=1.0
ratio_default=(ax.get_xlim()[1]-ax.get_xlim()[0])/(ax.get_ylim()[1]-ax.get_ylim()[0])
ax.set_aspect(ratio_default*aspectratio)
4b9b3361

Ответ 1

На самом деле то, что вы хотите, довольно просто... Вам просто нужно убедиться, что adjustable установлен на 'box' на ваших осях, и у вас есть установленное соотношение сторон для осей (ничего, кроме 'auto').

Вы можете сделать это с помощью adjustable kwarg при создании подзаголовков. В качестве альтернативы вы можете сделать это после их создания, вызвав ax.set_adjustable('box'), или позвонив ax.set_aspect(aspect, adjustable='box') (где аспект - либо 'equal', либо номер).

Теперь, независимо от того, как изменяется размер фигуры, подсети будут поддерживать одинаковое соотношение сторон.

Например:

import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(2,1,1, adjustable='box', aspect=0.3)
ax2 = fig.add_subplot(2,1,2)

ax1.plot(range(10))
ax2.plot(range(10))

plt.show()

Теперь сравните, как верхняя подзадача реагирует на изменение размера, а также то, как отвечает нижняя подзадача:


Начальный график alt text

Изменена по вертикали: alt text

Изменено на горизонтальную компоновку: alt text

Ответ 2

Ваше обходное решение работает для меня. После построения данных я вызываю следующую функцию:

def fixed_aspect_ratio(ratio):
    '''
    Set a fixed aspect ratio on matplotlib plots 
    regardless of axis units
    '''
    xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()

    xrange = xvals[1]-xvals[0]
    yrange = yvals[1]-yvals[0]
    gca().set_aspect(ratio*(xrange/yrange), adjustable='box')

Ответ 3

В ответ на замечание о том, что решение не работает для логарифмических графиков в редактировании исходного вопроса - вам нужно адаптироваться следующим образом:

def fixed_aspect_ratio_loglog(ratio):
    '''
    Set a fixed aspect ratio on matplotlib loglog plots 
    regardless of axis units
    '''
    xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()

    xrange = log(xvals[1])-log(xvals[0])
    yrange = log(yvals[1])-log(yvals[0])
    gca().set_aspect(ratio*(xrange/yrange), adjustable='box')

(Адаптация для полулогарифмических графиков теперь должна быть очевидной)