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)
Ответы
Ответ 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')
(Адаптация для полулогарифмических графиков теперь должна быть очевидной)