Пользователь
0,0
рейтинг
30 сентября 2013 в 20:46

Разработка → Подготовка графиков в MatLab из песочницы

В написании научных статей немалую часть времени занимает подготовка иллюстраций, графиков и диаграмм. Хочу поделиться некоторыми мыслями и примерами того, как можно ускорить этот процесс. Материал пригодиться тем, кто пользуется системой MatLab.

MatLab предоставляет широкие возможности по отображению графической информации в виде графиков, диаграмм, и т.п. Однако не всегда получаемые по умолчанию иллюстрации удовлетворяют требованиям оформления статей. Для этого в системе MatLab существует множество настроек. И чтобы ускорить подготовку иллюстраций предлагаю воспользоваться несколькими строчками кода, которые помогут помочь настроить отображение графиков.

Прежде всего, необходимо настроить шрифты, которые будут использоваться для вывода значений осей и надписей на графиках, что также помогает в случаях неправильного отображения надписей на русском языке:

set(0,'DefaultAxesFontSize',14,'DefaultAxesFontName','Times New Roman');
set(0,'DefaultTextFontSize',14,'DefaultTextFontName','Times New Roman'); 

Затем необходимо настроить размер графика и его положение на экране, например, с отображением на весь экран:

figure('Units', 'normalized', 'OuterPosition', [0 0 1 1]);

При необходимости вставляем название графика:

title('Название');

Далее можно включить построение нескольких графиков в одном окне, c использованием тех же осей и свойств графика:

hold on;%или hold all;

Строим графики с определенным цветом, стилем и толщиной линии:

plot(X2,Y2,':k','LineWidth',3);
plot(X2,Y3,':b','LineWidth',3);
plot(X2,Y4,'-.','Color',[.1 .7 .7],'LineWidth',3);
plot(X2,Y5,'--','Color',[.1 .4 .1],'LineWidth',3);
plot(X2,Y6,'r','LineWidth',3);

Вставляем легенду в график с определенным положением на рисунке, например справа внизу:

legend('исходные данные','полином 3-й степени','полином 4-й степени','полином 5-й степени','полином 7-й степени','полином 9-й степени', 4);

И вот тут начинается самое интересное...



При построении графика в MatLab дробные значения подписей на осях координат отображаются с разделителем в виде точки, тогда как, разделитель дробной и целой части у нас принято отображать запятой.

Чтобы не изменять вручную все значения подписей данных осей через меню графика,
воспользуемся небольшим куском кода:
BX=get(gca,'XTick');
BY=get(gca,'YTick');

xlabel(XL,'Position',[BX(size(BX,2)) BY(1)])
ylabel(YL,'Rotation',0,'Position',[BX(1) BY(size(BY,2))])

XA=get(gca,'XTickLabel');%

for i=1:size(XA,1)

    z=rem(i,2);
    if z==0;
        if XA(i,1)~='0' && XA(i,2)~=0
            XA(i,:)=char(0);
        end
    end
    
end

XA(size(XA,1),:)=char(0);

set(gca,'XTickLabel',XA);

YA=get(gca,'YTickLabel');%

for i=1:size(YA,1)

    z=strfind(YA(i,:),'.');
    YA(i,z)=',';
    clear z;
    z=rem(i,2);
    if z~=0; 
        YA(i,:)=char(0);
    end
    
end

YA(size(YA,1),:)=char(0);

set(gca,'YTickLabel',YA);


Код «прореживает» подписи осей x и y, а также исправляет точки на запятые в подписях на оси y. Для других осей необходимо повторить аналогичные процедуры.

И в заключении отобразим линии координатной сетки:

grid on;

Для удобства использования, чтобы не повторять каждый раз эти действия, заключаем написанный код в функцию, в параметрах которой указываются настройки отображения графиков и их данные.

Функция subgraphic
function result=subgraphic(X1,X2,Y1,Y2,Y3,Y4,Y5,Y6,Tit,TL,XL,YL,PL)

figure('Units', 'normalized', 'OuterPosition', [0 0 1 1]);

plot(X1,Y1,'o','LineWidth',2,'MarkerEdgeColor','k','MarkerFaceColor',[.49 1 .63],'MarkerSize',5);

if Tit 
    title(TL);
end

hold on;

plot(X2,Y2,':k','LineWidth',3);

plot(X2,Y3,':b','LineWidth',3);

plot(X2,Y4,'-.','Color',[.1 .7 .7],'LineWidth',3);

plot(X2,Y5,'--','Color',[.1 .4 .1],'LineWidth',3);

plot(X2,Y6,'r','LineWidth',3);

legend('исходные данные','полином 3-й степени','полином 4-й степени','полином 5-й степени','полином 7-й степени','полином 9-й степени', PL);

BX=get(gca,'XTick');
BY=get(gca,'YTick');

xlabel(XL,'Position',[BX(size(BX,2)) BY(1)])
ylabel(YL,'Rotation',0,'Position',[BX(1) BY(size(BY,2))])

XA=get(gca,'XTickLabel');%

for i=1:size(XA,1)

    z=rem(i,2);
    if z==0;
        if XA(i,1)~='0' && XA(i,2)~=0
            XA(i,:)=char(0);
        end
    end
    
end

XA(size(XA,1),:)=char(0);

set(gca,'XTickLabel',XA);

YA=get(gca,'YTickLabel');%

for i=1:size(YA,1)

    z=strfind(YA(i,:),'.');
    YA(i,z)=',';
    clear z;
    z=rem(i,2);
    if z~=0; 
        YA(i,:)=char(0);
    end
    
end

YA(size(YA,1),:)=char(0);

set(gca,'YTickLabel',YA);

grid on;

result=1;

Выполним
subgraphic(B,T,A,Y3,Y4,Y5,Y7,Dva_theta_0_5,Tit,'Название','{\itT}, \circC','{2{\phi}_{0,5}, град.',3); 
с заранее подготовленными данными.

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



По умолчанию MatLab отображает греческую букву «фи» как в кириллице «ф». Одним из способов отобразить привычную греческую букву «фи» с петлеобразным начертанием, является выбор специального шрифта c греческими буквами. Скачиваем, например, шрифт Greek Normal отсюда и устанавливаем. Просмотрев шрифт Greek в таблице символов, замечаем, что в этом шрифте буква «фи» существует в двух вариантах, причем для кода латинской «f» получим тот же результат что и в MatLab в виде «ф», а для кода латинской «j» должен быть получен требуемый результат.

Выполним
subgraphic(B,T,A,Y3,Y4,Y5,Y7,Dva_theta_0_5,Tit,'Название','{\itT}, \circC','{2\fontname{Greek}j}_{0,5}, град.',3);

И получим вот такой график:



В результате использования приведенного кода для построения графиков с помощью системы MatLab удалось:

  • Решить проблему с некорректным отображением кириллических шрифтов;
  • Автоматически заменить разделитель целой и дробной части числа с точки на запятую в графике;
  • Отобразить греческую букву фи в петлеобразном начертании.



PS Если кто-то знает простой способ отобразить символ греческой буквы «фи» с кодом unicode-03С6 в графиках MatLab, напишите пожалуйста в комментариях.

UPD Еще один способ, подсказанный в комментариях, для отображения «фи» с петлеобразным начертанием:
text(x, y, '$\varphi$', 'FontSize', 14, 'Interpreter', 'latex');


И несколько полезных ссылок:
Код на Github.com
Некоторые полезные средства настройки графиков (plot) в MATLAB
Заметки про Matlab. Экспорт графиков.
Простейшее приложение с GUI средствами MatLab 6.5
Михаил @mgorb
карма
2,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (25)

  • +1
    В качестве дополнения к статье (весьма полезной, между прочим) замечу, что Матлаб, в общем-то, предоставляет весьма скудные возможности по редактированию графиков. И мой коллега убедил меня использовать еще один этап подготовки--редактирование в векторном редакторе. Например, CorelDraw, Adobe Illustrator или Inkscape (последний--бесплатный, по функционалу вполне сравним с первыми двумя; что-то в нем хуже, а что-то лучше). Многие проблемы, тяжело- или вообще не-решаемые в Матлаб, можно решать уже там.
    • +1
      То есть workflow такой: делаем график в Матлабе->экспортируем в eps->импортируем в Illustrator /Inkscape->наводим окончательную красоту там->экспортируем во что хотим (eps или png).
      • 0
        У меня каждый график отрисовывается огромное количество раз — каждый раз, когда нашёл баг в коде, ошибку в данных, сделал другую гипотезу и т.п. Поэтому нереально делать неавтоматизированный workflow — график готовится в момент первого вывода данных, а в итоговый документ вставится вариант из последнего запуска программы.
        Мне пока что хватало стандартных средств MatLab. Расскажите, что вы не нашли, может помогу чем?
        • 0
          То, что графики часто надо перестраивать--это безусловно. Я имел в виду уже последний этап работы с ними--когда вы готовите график в статью или презентацию и точно знаете, какие данные там будут. Например, вы врядли сможете сделать сразу в матлабе
          именно такую картинку.
          image
          Некоторые из сложностей: размеры разных элементов текста, размеры показателей степени (они чуть больше, чем по умолчанию, иначе плохо видно), цвет рамки легенды, подписи легенды (два столбца), расположение легенды, расположение буквы (d) и т.п. Кроме того, это часть графика из четырех таких картинок (2 по горизонтали, 2 по вертикали). В матлабе вы тоже аккуратно не настроите нужные поля между картинками, выравнивание подписей к осям (цифры и текст). Кроме того, пришлось сместить "-1" при \gamma вниз, иначе на соседнем графике с такой же подписью "-1" была слишком близка к цифре 10 выше. И т.п. Но исходная картинка с кое-какими настройками была из Матлаба, и, конечно, она перестраивалась много раз перед окончательной подготовкой.
          • 0
            P.S. Почему-то habrastorage не хотел принимать картинку, экспортированную из CorelDraw, пришлось сделать print screen и вырезать кусок экрана с картинкой. Потому без антиалиасинга, извините. Так бы она была еще красивее :-)
          • 0
            Да, действительно, я не до такой степени вылизываю свои графики :-)
            Единственное, что могу сказать — букву (d) можно легко поставить через annotation, со всем остальным не сталкивался…
  • 0
    Столкнулся недавно с проблемой: необходимо было построить две поверхности, задаваемые уравнениями, на одном графике.
    Скажите, МатЛаб такое может? Мне порекомендовали SciLab…
    • 0
      Может, разумеется. 95% того, что может Матлаб, вообще едва ли понадобится одному человеку
      • 0
        Помогите, пожалуйста, нарисовать вот такие 2 поверхности:
        z=100-1.692*x/y
        z1=100-0.2524*x-0.008x^2-0.054*y^2+0.000136*x*y^2+0.00000432*x^2*y*2
        x=0..30
        y=0..20
        Буду признателен.
        • 0
          Пожалуйста:
          [x, y] = meshgrid(0:0.1:30, 0:0.1:20);
          z = 100 - 1.692 .* x ./ y;
          z1 = 100 - 0.2524 .* x - 0.008 .* x.^2 - 0.054 .* y.^2 + 0.000136 .* x .* y.^2 + 0.00000432 .* x.^2 .* y .* 2;
          surf(x, y, z);
          hold on;
          surf(x, y, z1);


          Вообще в матлабе чрезвычайно мощный хелп (один из лучших, что я когда-то либо видел), 90% ответов на вопросы можно найти прямо там.
          • 0
            Спасибо большое!
            Но на матлаб у меня физически времени не хватает. До этого с такими проблемами не сталкивался — обрабатывал результаты и представлял их, в основном, средствами Excel, AdGrapher и CurveExpert. Хватало :) А ради одной небольшой нетривиальной задачи каждый раз погружаться в дебри очередного незнакомого пакета, при этом совсем не юзер-френдли (в отличие, например, от маткада) никакой жизни не хватит. Все знать невозможно, а стремление в познании должно быть обосновано профитом, отнесенным к потраченному времени…
        • 0
          image
          image

          Могу оформить как CDF и вы сможете этот график в браузере посмотреть, как тут: Introducing the Computable Document Format (CDF).
          • 0
            Спасибо огромное! Красота неописуемая :)
            • 0
              На всякий случай, прямые ссылки на habrastorage:
              1. код
              2. график
  • 0
    Для правильной φ попробуйте использовать символ \varPhi. Если там более-менее нормальный TeX, должно прокатить.
  • 0
    text(0.1, 0.8, '$\varphi$', 'FontSize', 20, 'Interpreter', 'latex')
  • 0
    Спасибо redliner
    text(0.1, 0.8, '$\varphi$', 'FontSize', 20, 'Interpreter', 'latex')

    в таком варианте действительно работает
  • 0
    Еще одна статья про рабовладельческое ПО. Напишите лучше статью про Octave+gnuplot
    • +2
      Напишите. Никто же не заставляет вас это читать. А то дойдём до комментариев «напишите лучше про Бритни Спирс, она мне больше MatLab нравится!»
  • 0
    Из открытого ПО отличная библиотека matplotlib для для питона. Умеет и LaTeX вставлять на графики и в форматы различные сохранять.Возможности можно оценить на на страничке примеров .
  • 0
    Графики в матлабе предоставляют довольно много возможностей, но нет тривиальных вещей, вроде поворота меток на осях. Даты, например, отображать очень неудобно. Ещё в матлабе беда с производительностью графической подсистемы. То есть она просто никакая. Графики с большим количеством данных тормозят безбожно. Интерактивные инструменты визуализации тоже оставляют желать лучшего. Если кому нужно, я когда-то давно написал функцию для интерактивного взаимодействия с 2D, 3D графиками. А вообще, лучше пользоваться Python+Matplotlib. Matlab непомерно дорог.
  • 0
    А кто-нибудь знает, как в MatLab синхронизировать две оси Y? То есть, у меня есть два графика, у каждого своя ось Y (слева и справа), и я хотел бы сделать так, чтобы у них, например, совпадали начала отсчёта. Или какие-то другие, заданные мною точки, были бы напротив друг друга. Есть, конечно, вариант всё просчитать самому (YLim, YTicks и т.п.), но наверняка же я не первый человек, столкнувшийся с этой проблемой, вполне возможно, есть уже какая-то работающая функция…
    • 0
      Для случайных прохожих: функция называется linkaxes.
  • 0
    есть пакет export_fig, который много чего умеет и его код можно использовать, как примеры
  • 0
    Изменения в графической системе R2014b:
    matlab.ru/blog/MPblog/MATLAB_HG2

    Там про графики как раз

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.