Я использую mpl_toolkits.basemap (Basemap), который возвращает цифры с фиксированными пропорциями. Мне нравится группировать несколько графиков из Basemap на один рисунок.gridspec с субфигурами, которые имеют фиксированное соотношение сторон
Проблема: Базовая карта в сочетании с gridspec создает большие пробелы между подзаголовками.
Вопрос: Как удалить пробел между подзаговорами в этом случае? Альтернативно, могу ли я позволить подзаголовкам заполнять фигуру сверху вниз, а затем обрезать левую над белым пространством?
Требование является то, что ширина рисунка (например, fig_width = 0,4) представляет собой часть страницы формата А4 (т.е. A4_width = 21см), а высота рисунка должен быть большим, чтобы позволить Basemap масштабировать график свободно.
Ниже приведены два примера: (a) один с большой длиной оси Y и (b) тот, где длина оси y выбирается вручную для приближения желаемого результата.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from mpl_toolkits.basemap import Basemap
def plot_figure(fig):
x = np.arange(20)
y = np.arange(10)
Z = np.outer(y, x)
nrow, ncol = 0, 0 # counter for axis position from gridspec
nrows, ncols = 6, 4 # number of gridspec columns and rows
ax = {}
for n in xrange(11):
# use gridspec for the wspace and hspace options
gs = gridspec.GridSpec(nrows = nrows, ncols = ncols)
gs.update(left=0.05, right=0.48, wspace=0.1, hspace=0.1)
ax[str(n).zfill(2)] = plt.subplot(gs[nrow, ncol])
# plot with Basemap
width, height, lat_ts, lat_0, lon_0 = 2.5e6, 1.2e6, 5., 5., 10.
m = Basemap(width = width, height = height, resolution = 'c', projection = 'laea',
lat_ts = lat_ts, lat_0 = lat_0, lon_0 = lon_0)
X, Y = np.meshgrid(x, y)
mX, mY = m(X, Y)
parallels = m.drawparallels(np.arange(-10.,30.,5.), labels=[1,0,0,0] if ncol == 0 else [0,0,0,0])
meridians = m.drawmeridians(np.arange(-20.,20.,5.), labels=[0,0,1,0] if nrow == 0 else [0,0,0,0])
cf = m.contourf(mX, mY, Z);
# go through the axis coordinates
if ncol < ncols - 1 :
ncol += 1
else :
ncol = 0
nrow += 1
A4_width, A4_height = 21/2.54, 29.5/2.54
(а) Теперь с большой оси Y длины (желательно, но не так):
fig_width, fig_height = 0.85, 1.0
f1 = plt.figure(figsize=(fig_width * A4_width, fig_height * A4_height))
plot_figure(f1)
plt.savefig('f1.pdf', format='pdf', bbox_inches='tight')
tight_layout, кажется, не работает здесь
# gs.tight_layout(f1)
вызывает ошибку:
'UserWarning: This figure includes Axes that are not compatible with tight_layout, so its results might be incorrect. warnings.warn("This figure includes Axes that are not "'
(б) С вручную установить по оси Y длины (нежелательна, однако результат ОК):
fig_width, fig_height = 0.85, 0.4
f2 = plt.figure(figsize=(fig_width * A4_width, fig_height * A4_height))
plot_figure(f2)
plt.savefig('f2.pdf', format='pdf', bbox_inches='tight')
Я не понимаю, что плохого в подходе (б), если результат выглядит, как вы хотите. Можете ли вы уточнить, какое у вас требование? – ImportanceOfBeingErnest
Подход (б) в порядке, однако мне нужно несколько раз посмотреть на рисунок, пока я не получу приблизительный минимум (или даже количество в х и у) пробела между отдельными подзаговорами.Мне в основном интересно, если есть другой способ справиться с фиксированными пропорциями, что требует меньше ручной настройки. –
По существу, 'fig_height' может быть любым значением от 0 до 1, и проблема в том, что вы не хотите сами узнать это значение ?! Неужели 'tight_layout' не работает или это просто бросает предупреждение? Является ли результат, который вы получите с нормальными (не Basemap) графиками вместе с 'tight_layout', чтобы эти требования удовлетворяли? У вас всегда есть одна и та же сетка (например, 3x4) или это меняется? У вас всегда есть одни и те же образы аспектов или должно ли решение быть независимым от аспекта изображений? У меня нет идеи для решения прямо сейчас, но это важные вещи, которые должен знать потенциальный ответчик. – ImportanceOfBeingErnest