2011-01-20 5 views
19

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

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

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

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) 

ответ

15

На самом деле, то, что Вы желаете довольно просто ... Вам просто нужно, чтобы убедиться, что 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

+0

Я стою исправлены. Хорошо знать. –

+0

Привет! Спасибо за ваш ответ. К сожалению, это устанавливает только соотношение сторон осей подзаголовков. Поскольку у меня много разных диапазонов моих осей, мне пришлось бы установить это соотношение сторон для каждого подзадачи в отдельности.Так что я хотел бы сделать, чтобы установить высоту и ширину моих подзадач (а не только осей) на конкретное соотношение сторон. –

3

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

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

Это сработало для меня. Я изменил функцию, чтобы принять аргумент 'ax', чтобы я мог применить его к подзаголовкам. Я также заменил 'gca(). Axes'' ax' и 'gca()' на 'ax'. – Steve

1

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

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

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

Смежные вопросы