Убираем пустое пространство вокруг карты в MATLAB
Сегодня мы, может быть и не изящным образом, но избавимся от пустого пространства, которое возникает при построении карт в MATLAB.
Для начала посмотрим на проблему. Сделаем простейшее построение карты в MATLAB:
worldmap([50 70],[-20 20])

Такой вариант вполне неплох, хотя возможно вам уже кажется, что пустого пространства вокруг карты слишком много (чтобы лучше было это видно, вы можете открыть картинку в отдельной вкладке вашего браузера).
Теперь попробуем немного усугубить ситуацию:
worldmap([50 70],[-60 20])

И вот мы видим MATLAB во всей своей красе. Автоматика при построении карт работает отвратительно и уже много лет MATLAB не хочет с этим ничего делать. Во-первых, значения долгот неприлично близко расположены друг к другу, но давайте это сразу поправим:
worldmap([50 70],[-60 20])
setm(gca, 'mlabellocation',[-60:10:20])

Ну и во-вторых, белого пустого пространства теперь слишком много. Часто проблема решается, если вы мышкой схватите окно с картинкой за край и начнёте менять его размер вручную, однако это не всегда приводит к хорошему результату.
Когда вы имеете дело с простыми графиками в MATLAB, то пустое пространство достаточно просто ликвидировать автоматически и на официальном сайте есть инструкция, как это сделать: Save Plot with Minimal White Space. Отдельную функцию им было сделать, видимо, лень. Если вдруг ссылка устарела, продублирую решение здесь. Достаточно запустить (после построения вашей картинки) следующий код:
ax = gca;
outerpos = ax.OuterPosition;
ti = ax.TightInset;
left = outerpos(1) + ti(1);
bottom = outerpos(2) + ti(2);
ax_width = outerpos(3) - ti(1) - ti(3);
ax_height = outerpos(4) - ti(2) - ti(4);
ax.Position = [left bottom ax_width ax_height];
Здесь OuterPosition — позиция полной картинки (окна, в котором построена диаграма, карта и т.п.) вместе с любыми пустыми пространствами, Position — размер построенной вами диаграммы (без подписей к осям), а TightInset — это границы вместе с подписями к осям.
Проблема заключается в том, что с нашей картой такое не прокатит. Т.е. если вы запустите вышеупомянутый код, то получите вот что (срежите все крайние значения долгот и не избавитесь полностью от пустого пространства сверху и снизу):

Насколько я понял, корень проблемы заключается в том, что параметр TightInset, который по идее должен выдавать информацию о том, какой размер занимают подписи к осям, неадекватно работает при построении карт или вообще такого понятия в mapping toolbox нет.
Скажу честно, на данный момент, я не знаю хорошего решения этой проблемы, если я его найду, то обязательно напишу об этом отдельную заметку. Ну а пока выдам простой и тупой, но рабочий вариант.
Для начала сделаем несколько манипуляций, которые помогут понять дальнейшие действия. Получим информацию об окне, в котором появилась ваша только что построенная картинка.
fi= gcf;
fi.Position
fi.Position =
440 378 560 420
Эти цифры будут зависеть он разрешения экрана. Эсли вы взьмёте окно с картинкой и начнёте двигать его в разные стороны, то будут меняться перые две цифры (это координаты нижнего левого угла окна и отсчитываются они от нижнего левого угла экрана, первое число (440) — растояние от этого угла экрана в пикселях по горизонтали, а второе (378) — по вертикали). Если вы начнёте менять размеры окна с картинкой, то будут меняться вторые две цифры (это ширина (560) и высота (420) окна всё в тех же пикселях). Т.е. полный размер вашего окна с какртинкой 560х420 пикселей.
Теперь получим информацию об осях карты, т.е. позиция этих осей внутри нашего окна fi. Заметьте, что для единообразия мы перевели единицы измерения в пиксели (ax.Units=’pixels’), ведь по умолчанию они исчисляются в условных еденицах:
ax = gca;
ax.Units='pixels';
ax.OuterPosition
ax.OuterPosition =
1 1 560 420
ax.Position
ax.Position =
73.8000 47.2000 434.0000 342.3000
Обратите внимание, что ax.OuterPosition очень похоже на размер нашего окна в пикселях (560х420), несложно догадаться, что OuterPosition определяет полные границы наших осей в координатах, в которых ноль расположен в левом нижнем углу нашего окна с картинкой, а не в углу экрана (как это было с параметром fi.Position) . На самом деле ax.OuterPosition я привёл для наглядности и далее мы его использовать не будем. Нам важнее параметр ax.Position, который определяет границы нашей карты без подписей и прочего пространства вокруг и начало координат также имеет в углу окна с картинкой, а не в углу экрана. Т.е. если мы выставим ax.Position=[1 1 560 420] или, что по сути одно и то же:
ax.Position=ax.OuterPosition
то получится такая карта:

Ну и теперь, как я уже говорил, я могу пока только посоветовать подбирать значения, для того, чтобы избавиться от лишнего белого пустого пространства. У меня после подбора получились такие значения (т.е. нижеописынными командами мы и задаём новые значения расположения осей и окна):
fi.Position = [440 378 629 350]
ax.Position = [40 -30 560 420]
Обратите внимание, что в fi.Position я изменил только последние два значения (было [440 378 560 420], стало [440 378 629 350]), отвечающие за ширину и высоту окна. Оставив неизменными первые два значения я оставил левые нижний край окна в том же месте, где он был изначально, т.е. смысла двигать окно с картинкой в разные стороны по экрану не было никакого. В ax.Position третье и четвёртое значение я решил выставить на 560 и 420, для того чтобы пропорции исходной картинки не изменились и дальше их не менял, играясь только с первыми двумя значениями, отвечающими за положение левого нижнего угла (и да получилось так, что начало оси пришлось вынести за начало координат (-30)). Вот что в итоге получилось:


Чтобы не пропустить новые материалы с рецептами по работе с океанологическими данными, подпишитесь на канал в Telegram: https://t.me/koldunovaleksey