ЛаТеХ для продвинутых. Как подружить LaTeX и MATLAB: вставка рисунков из MATLAB в документы LaTeX

В документе всё должно быть прекрасно — и текст, и картинки

Благодаря ЛаТеХу научные работники (и не только) получили возможность создавать красивые, уравновешенные документы с чётко просматривающейся структурой. Однако "сфера влияния" ЛаТеХа распространяется только на текст и формулы, а внешний вид графиков и иллюстраций находится полностью на совести автора. И вот здесь-то и начинаются полные разброд и шатания: на некоторые рисунки трудно смотреть без слёз :)

Целью данного поста является продемонстрировать один из способов создания математических графиков гармонично сочетающихся с окружающим их текстом.

Постановка задачи

Что отличает рисунок гармонично вписывающийся в основной текст от рисунка плохого? Безусловно, содержание, размер и расположение являются важными эстетическими параметрами. Однако наиболее бросающимся в глаза диссонансом, свойственным львиной доле естественно-научных рисунков, являются шрифты. Да-да, именно шрифты... Речь идёт о подписях к осям графиков, о легендах и т.п. Порой создается ощущение, что у автора серьёзные проблемы со зрением: скажем, рядом с текстом набранным Times 12pt вдруг оказывается график с подписями 16-ым шрифтом... Или, ещё лучше, нечитаемым 8-ым... А о соответствии типа шрифта (начертания) между рисунками и текстом и мечтать не приходится!

Итак, наша основная задача: графики, шрифт на которых совпадает по размеру и начертанию с основным шрифтом документа.

Все дороги, которые ведут в Рим

Достичь нашей цели можно разными путями. Наиболее общеизвестные из них, в порядке убывания ортодоксальности:

  1. Использовать LaTeX для построения графиков. На деле это означает либо использование pgfplots и tikz, либо pstricks.
  2. Использовать около-ЛаТеХные средства, хорошо взаимодействующие с ЛаТеХом. Например, MetaPost или Asymptote.
  3. Использование вашей любимой программы (например, Matlab, Mathematica, Gnuplot и т.д. в сочетании с тем или иным способом конвертации в "ЛаТеХ-код", скажем tikz. Более конкретно: например, matlab2tikz. Или tikz терминал для Gnuplot.
  4. И, наконец, использование вашей любимой программы, как и в предыдущем пункте, с сохранением картинки как eps или pdf и последующей "подменой текста", a la psfrag и т.п.

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

В этом посту мы рассмотрим алгоритм экспорта графиков из MATLAB в LaTeX.

Выбор Матлаба для построения графиков диктуется исключительно личными предпочтениями автора. Аналогичные методы применимы и к другим программам — об этом в самом конце.

Как ЛаТеХ с Матлабом подружить

Цель

Собственно: экспорт графиков из Матлаба в ЛаТеХ. При этом предполагается, что подписи и т.п. на графике должны сочетаться с основным текстом.

Желаемый результат изображен ниже. Специально выбран нестандартный фонт (Kepler-подобный из kpfonts вместо стандартного Computer Modern), чтобы подчернуть желаемый эффект.

Средства

Матлаб, версии новее 7.6 (release name 2008a). Кроме того, скрипт matlabfrag.m. Его можно скачать самостоятельно, но он (вернее его улучшенная версия) есть и в архиве с примерами из этого поста: tinyurl.com/amorua-matlabfrag. Поместите его в текущую директорию: туда где будут находиться ваши скрипты для построения графиков. Поместите туда же файлы myfigure.m и mylegend.m из того же архива с примерами.

ЛаТеХ. Нам понадобится пакет pstool, причём версия 2013/02/11 v1.5 или новее. В старых версиях пакета будет работать всё, кроме ссылок из картинок на основной документ, например, на уравнения или номера страниц. Файл pstool.sty нужной версии находится в архиве с примерами. Все примеры можно компилировать либо
pdflatex -shel-escape имя-файла
либо
latex -shell-escape имя-файла
dvips имя-файла
pstopdf имя-файла.ps

но предпочтение должно быть отдано первому варианту.

Если -schell-escape опция не работает, возможно в вашей версии ЛаТеХ она называется -enable-write18.

Строим график

Здесь всё почти как обычно:

01:  %% example 1
02:  close all ; clear all; clc;
03:  %% Интерпретатот текста, по умолчанию, latex
04:  set(0,'DefaultTextInterpreter', 'latex');
05:  %  Размер шрифта такой же как в ЛаТеХ-документе
06:  set(0,'DefaultAxesFontSize',12);
07:  set(0,'DefaultTextFontSize',12);
08:  
09:  %% Создаём картинку   
10:  fig=figure;
11:  %% Рисуем графики ...
12:  x=0:0.1:pi;
13:  y=sin(x); plot(x,y,'r'); hold on;
14:  z=cos(x); plot(x,z,'b');
15:  
16:  %% Подписи к осям
17:  xlabel('$t$, s'); ylabel('$l$, m');
18:  %% Легенда
19:  l=legend('$\sin x$','$\cos x$');
20:  
21:  %% Дополнительный текст на графике
22:  text(0.5,-0.5,'$\int\limits_0^{2\pi}\sin x\, dx = 0$');
23:  text(3,-0.5,'$\gamma = \frac{\alpha}{\zeta}$');
24:  
25:  %% Экспортируем график 
26:  matlabfrag('figs/example1','epspad',[10,10,10,10]);

Теперь по порядку:

  1. В строке 4, latex установлен как интерпретатор текста по умолчанию. Благодаря этому, в подписях к осям (строка 17), легенде (строка 19) и дополнительном тексте (строки 22, 23) мы можем спокойно использовать ЛаТеХ-комманды.
  2. Затем, надо проинформировать Матлаб о том, что весь текст мы хотим набирать 12-ым шрифтом (если используется используется "улучшенная" версия matlabfrag из архива с примерами, то устанавливать размер шрифта не надо — будет автоматически подхвачен текущий размер из ЛаТеХ-документа).
  3. После того как всё готово, в строке 26, использована функция matlabfrag() для сохранения графика. Она создаст два файла: figs/example1.eps и figs/example1.tex (предполагается, что в текущей директории вы создали поддиректорию figs/, куда мы будем складывать все картинки). Если посмотреть на их содержимое, то станет понятно, как это всё работает.
    Сама картинка находится в eps-файле, но вместо текста там "числа-заглушки", вроде 000, 001, 002 и т.д. В tex-файле же находится весь текст в виде, понятном ЛаТеХу.
    Теперь дело за ЛаТеХом.

Вставляем график в документ ЛаТеХ

Как видно из предыдущего рисунка, ЛаТеХ-текст будет вставлен с помощью команды \psfrag из одноимённого пакета. Однако, гораздо удобнее пользоваться им не напрямую, а через интерфейс, предоставляемый пакетом pstool. Делается это так: подключаем пакет pstool и вставляем картинку командой \psfragfig{}.

01:  \documentclass[12pt]{article}
02:  ...
03:  \usepackage{pstool} 
04:  ...
05:  \begin{document}
06:  ...
07:  \begin{figure}\centering
08:    % вставляем картинку: 
09:    % имя файла без расширения!!!
10:    \psfragfig{figs/example1}
11:    \caption{Example of a Matlab plot.}\label{fig:ex1}
12:  \end{figure}
13:  ...
14:  \end{document}

Обратите внимание, что имя файла картинки без расширения. Если картинка находится не в текущей директории, то нужно указать путь к ней.

Кроме того, размер шрифта в самом первой строке установлен в 12pt, в соответствии с размером шрифта на рисунке в Матлабе.

Компилируем командой
pdflatex -shell-escape имя-тех-файла
Пакет pstool сделает за нас всю чёрную работу: он сам сконвертирует на лету связку файлов eps+tex в pdf картинку и вставит её: он прогонит автоматически каждую картинку через ЛаТеХ, dvips и pstopdf. Именно для этого и надо указать ключ -shell-escape при запуске pdflatex — он разрешает пакету запускать внешние программы.

Пакет pstool достаточно разумен: он смотрит на дату создания файлов картинок и "конвертирует" только изменившиеся со времени последнего запуска. Чтобы принудительно переконвертировать все картинки, надо указать опцию process=all, а именно

01:  ...
02:  \usepackage[process=all]{pstool} 
03:  ...
Результат наших усилий показан внизу. Как видите, на графике использованы Computer Modern шрифты ЛаТеХа, размер которых совпадает с размером, использованным в тексте (см. подпись к рисунку).

Тонкая настройка

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

Деталь нулевая

Деталь, к matlabfrag() прямого отношения не имеющая, но тем не менее... Наилучшего, с эстетической точки зрения, результата можно добиться, если вставлять в ЛаТеХ рисунки в том масштабе, в котором они были нарисованы. Т.е. рисовать их лучше сразу в нужном размере! Для этого создаём в Матлабе простенькую функцию

01:  function h=myfigure(width,height)
02:  % создаёт figure с заданной шириной и высотой в см
03:  
04:  if nargin<2 % если дана только ширина, использует золотое сечение для высоты
05:      height = width * 2/(1+sqrt(5)); % высота=ширина/золотое сечение
06:  end
07:  
08:  set(0,'units','centimeters')
09:  scrsz=get(0,'screensize'); % размер экрана в см
10:  % положение и размер картинки
11:  position=[scrsz(3)/2-width/2 scrsz(4)/2-height/2 width height];
12:  h=figure;
13:  set(h,'units','centimeters')
14:  % устанавливаем размер
15:  set(h,'position',position)
16:  % Set screen and figure units back to pixels
17:  set(0,'units','pixel')
18:  set(h,'units','pixel')
Если использовать myfigure(10,8), то размер картинки будет 10см на 8см. Если задать только первый аргумент myfigure(10), то функция сама посчитает высоту исходя из золотого сечения. Файл myfigure.m находится в архиве с примерами.

Деталь первая: UserData matlabfrag

В принципе, необязательно пользоваться интерпретатором latex в Матлабе. Функция matlabfrag() смотрит на свойство UserData и, если оно имеет вид matlabfrag:XXX, вставляет XXX в качестве ЛаТеХ-текста. Например, код ниже делает в точности то же самое, как и разобранный выше пример

01:  %% example 2
02:  close all ; clear all; clc;
03:  %% По умолчанию, интерпретатор текста tex, а не latex,
04:  %  т.е. set(0,'DefaultTextInterpreter', 'tex'); указывать не обязательно
05:  
06:  %% Создаём картинку   
07:  fig=myfigure(10);
08:  %% Рисуем графики ...
09:  x=0:0.1:pi;
10:  y=sin(x); plot(x,y,'r'); hold on;
11:  z=cos(x); plot(x,z,'b');
12:  
13:  %% Подписи к осям
14:  xlabel('t, s', 'UserData','matlabfrag:$t$, s'); 
15:  ylabel('l, m', 'UserData','matlabfrag:$l$, m');
16:  %% Легенда
17:  l=mylegend({'sin x';'cos x'},...
18:             {'$\sin x$';$\cos x$});
19:  
20:  %% Дополнительный текст на графике
21:  text(0.5,-0.5,'integral here',...
22:       'UserData','matlabfrag:$\displaystyle \int\limits_0^{2\pi}\sin x\,dx = 0$');
23:  
24:  text(3,-0.5,'\gamma = \alpha/\zeta',...
25:      'UserData','matlabfrag:$\displaystyle \gamma=\frac{\alpha}{\zeta}$'); 
Недостаток этого способа в том, что придётся набирать больше текста. Кроме того, картинка, как её покажет Матлаб, вообще говоря, будет отличаться от той, которую вы увидите в ЛаТеХе.

Зато такой способ гораздо более гибок. Он позволяет вставлять в текст подписей команды, определённые в ЛаТеХ документе, о которых Матлаб ничего не знает. Например:

01:  text(0.5,-0.5,'integral here',...
02:   'UserData','matlabfrag:\myint see eq.(\ref{eq:1})');
использует команду \myint, а кроме того, ссылается на уравнение из основного текста.

Обратите внимание на то, как добавляется UserData к легенде: здесь для облегчения процесса использована функция mylegend(легенда,латех_вариант). Она принимает два аргумента, оба cell array. Первый — легенды для Матлаба, второй — для ЛаТеХа.

01:  function l=mylegend(lgnds,usrdta_in)
02:  % функция для создания легенд с ЛаТеХ-вариантами
03:  % пример вызова: l=mylegend({'sin(x)';'cos(x)'},{'$\sin x$';'$\cos x$'})
04:  % возвращает указатель на легенду
05:    l=legend(lgnds);
06:  
07:    if nargin>1 % если переданы UserData
08:       usrdta=lgnds;
09:       for i=1:min(length(usrdta),length(usrdta_in))
10:      usrdta{i} = usrdta_in{i};
11:       end
12:      
13:       lchild=get(l,'children');
14:       i_max=length(usrdta);
15:    
16:       for i=1:i_max
17:           i_child=3*i_max-(i-1)*3 ;
18:           set(lchild(i_child),'Userdata',sprintf('matlabfrag:%s',usrdta{i}));
19:       end
20:    end
21:  end

Дело в том, как Матлаб хранит текстовое содержимое легенд: если легенды две, то их текст будет сохранен в 6-м и 3-м элементах "детей легенды". Если легенды три, то в 9-м, 6-м и 3-м. И так далее.

Файл mylegend.m может быть найдена в архиве с примерами.

Деталь вторая: текстовые эффекты

Функция matlabfrag() настолько сообразительна, что автоматически подхватит эффекты, такие как вращение текста, центрирование, цвет, размер и т.п. Например, такой код

01:  %% example 3
02:  %% Text effects
03:  text(2.5,-0.5,{'Rotated';'text'},'Rotation',90);
04:  
05:  text(0.5,-0.5,{'Colored';'centered';'italic';'text'},...
06:      'Color','r',...
07:      'HorizontalAlignment','center',...
08:      'FontAngle','italic');
09:  
10:  text(1,-0.5,{'Big Text:';'16pt'},'FontSize',16)
даст эффект, очевидный из картинки ниже.

Обратите внимание, что для набора текста в несколько строк использованны cell arrays, вроде {'строка один';'строка два'}. Этот трюк работает не только для функции text(), но и для, например, подписей на осях:

01:  xlabel({'$t$, s'; 'time to goal'}); 
02:  ylabel({'$l$, m'; 'distance to goal'});

Деталь третья: поддержка русского языка

С русским тоже никаких проблем: просто, набираем подписи и текст на русском. Только не забываем в ЛаТеХ-документ вставить в преамбулу

01:  \usepackage[utf8]{inputenc}
02:  \usepackage[T2A]{fontenc}
03:  \usepackage[russian]{babel}

Результат:

Деталь четвертая: подписи к меткам на осях

Иногда хочется заполучить у меток на осях не числа типа 3.14, а что-то посимпатичнее, вроде числа "пи". Делается это просто:

01:  %% example 4
02:  ...
03:  %% подписи у меток, aka tick marks
04:  set(gca,'XLim',[0 pi],'XTick',[0 pi/2 pi],...
05:       'XTickLabel',{'$0$','$\pi/2$','$\pi$'});

Всё остальное — как прежде. Результат:

Деталь пятая: необязательные аргументы matlabfrag()

Функция matlabfrag(), помимо обязательного имени файла, принимает ещё несколько опций: handle, epspad, renderer и dpi. Например,

01:  matlabfrag('figs/myfig','handle',h,'epspad',[10 10 10 10])
сохранит в файлы figs/myfig.tex и figs/myfig.eps не активную в данный момент картинку, а ту, на которую указывает h; кроме того, добавит по 10px со всех сторон. Про renderer и dpi можно почитать в документации.

Деталь шестая: необязательные аргументы \psfragfig{}

Прежде всего, поведением pstool можно управлять задав опции при загрузке пакета. Одну из них, которая принудительно перекодирует все картинки, мы уже обсуждали: process=all.

Иногда метки, выдающиеся далеко за пределы графика, оказываются "обрезанными". Предотвратить такое поведение можно задав опцию crop=pdfcrop.

Если возникают непонятные проблемы со вставкой картинок, можно задать опцию mode=errorstop, чтобы процесс комиляции останавливался при возникновении ошибки.

На этом список опций не исчерпывается: за подробностями всегда можно обратиться к документации.

Все эти опции можно задавать не только при загрузке пакета, но и после, а именно:

  1. с помощью команды \pstoolsetup{}; опция будет применена с момента её объявления
  2. в качестве необязательных аргументов к \psfragfig{}; при этом опция будет применена только к текущей картинке; например
    01:  \psfragfig[crop=pdfcrop]{figs/myfig}
    

Деталь седьмая: лезем в код matlabfrag()

Одним (пожалуй, единственным) из недостатков matlabfrag() является то, что всегда надо указывать явно размер шрифта (посмотрите на строки 6 и 7 самого первого примера, см. также ниже), чтобы он совпадал с размером шрифта в ЛаТеХе. Тогда как гораздо более удобным, по мнению автора этих строк, поведением было бы следующее: (1) если размер шрифта не указан, то просто используется установленный ЛаТеХом; (2) если же мы указываем в Матлабе размер шрифта явно, через FontSize, то и в ЛаТеХе надо этот размер насильно применить.

К сожалению, в "ванильной" версии matlabfrag() такая возможность отсутствует. Однако в версии, которую можно найти в файле с примерами к этому посту, я взял на себя смелость и изменил код этой функции соответствующим образом. Т.е., если вы используете эту "хакнутую" версию, то указывать

01:  %  Размер шрифта такой же как в ЛаТеХ-документе
02:  set(0,'DefaultAxesFontSize',12);
03:  set(0,'DefaultTextFontSize',12);
не нужно.

Деталь восьмая и последняя: хочу другой шрифт

До настоящего момента мы стремились использовать на графиках шрифт того же начертания, что и в основном тексте. Однако "в узких кругах существует мнение", что хотя в основном тексте лучше использовать шрифт с насечками (serif font), на рисунках надо отдать предпочтение шрифту без насечек (san serif font). Выражаясь языком понятным пользователям Ворда, "в тексте: Times New Roman, на рисунках: Arial". Якобы, такое разделение привлекает внимание к рисункам и выделяет их в массе текста.

Хотя эстетическая ценность такого решения весьма сомнительна, в "улучшенной" версии matlabfrag.m реализована такая возможность. В преамбулу ЛаТеХ-документа помещаем

01:  \usepackage{sansmath}
02:  \providecommand{\MATLABFont}{\sffamily\sansmath}
и наслаждаемся результатами. Заметьте, что сами рисунки для этого "перерисовывать" не надо. Результат с и без \MATLABFont приведён ниже. Обратите внимание, что греческие буквы недоступны в начертании "без насечек".


В принципе, выше были рассмотрены все основные шаги и опции для сохранения графиков и их импорта в ЛаТеХ. Интересующиеся более подробно деталями процесса могут ознакомиться с документацией к matlabfrag и pstool.

Заключение и выводы

Итак, подведём итоги. Описанный метод позволяет при сравнительно малых затратах времени добиться более чем удовлетворительных результатов: векторных графиков с надписями, выполненными ЛаТеХом. Это позволяет не только добиться гармоничного соответствия между шрифтами на рисунке и в тексте, но и использовать на рисунке формулы и ссылки на уравнения, другие рисунки и т.д.

В случае Матлаба, необходимая функциональность доступна через matlabfrag(). Использование пакета pstool позволяет существенно упростить процесс импорта сгенерированных таким образом eps-файлов в pdfLaTeX.

Хотя мы рассмотрели данный рецепт на примере Матлаба, аналогичные методы могут быть использованы и с другими программами. Например, MathPSfrag является аналогом mathlabfrag() для мат-пакета Mathematica. Для Gnuplot использование set terminal latex и экспорт через pstool также позволяют добиться сходного результата.

Здесь мы рассмотрели экспорт графиков функций из MATLAB, однако схожий трюк применим и к рисункам и схемам созданным, например, в Inkscape. Об этом в одном из следующих постов.

Все примеры из данного поста доступны для скачивания по адресу tinyurl.com/amorua-matlabfrag.

Зеркала на случай сбоязеркало1, зеркало2

39 комментариев: |высказаться!| RSS-лента дискуссии.|
infroma комментирует...

Для тех, кто любит Python/пользовался Sage рекомендую SageTeX. http://www.sagemath.org/doc/tutorial/sagetex.html
Sage (http://ru.wikipedia.org/wiki/Sage) — математический пакет, состоящий из Python и кучи библиотек. SageTeX позволяет вставлять результаты вычислений (в том числе, и графики, которые делаются при помощи matplotlib) в LaTeX-документ. По идее, кросплатформенно, но я проверял только под Linux. Недостаток в том, что нужно лишний раз прогонять build.

virens комментирует...

@infroma комментирует...

Для тех, кто любит Python
Мы любили бы его больше, если бы он не был такой чудовищной кашей с плохой обратной совместимостью. Гвида ван Россум выкатила Пи(с)тон 3, и теперь народ говорит, что нужно портировать код на 3-ю версию. Портировать!

Sage (http://ru.wikipedia.org/wiki/Sage) — математический пакет, состоящий из Python и кучи
Вот именно, что из кучи. Матлаб хорош тем, что это хорошо организованная и продуманная система, в которой есть всё, что надо. Даже BLAS/LAPACK положили. И знаешь, что, infroma? Они там таки работают, в отличие от хвалёного Дебиана, где CLAPACK выкинут, а LAPACKE положен так, что нихрена не работает.

По теме поста - ну что сказать, отлично, amorua! Я вот не знал про matlabfrag.

У меня workflow несколько иной: я делаю матлабовские скрипты для анализа данных, и записываю данные в текстовые файлы с разметкой (по колонкам). Далее на питоне пишется (а чаще используется уже готовый) скрипт для генерации многих графиков Gnuplot сразу (в цвете\ЧБ, для разных наборов данных и проч.). Плюс в том, что данные остаются в текстовом виде, и если графики потерялись - можно построить заново.

Михаил Саушкин комментирует...

Спасибо за интересный пост, по аналогии раньше поступал с maple.
К сожалению, нет возможности сейчас использовать ни matlab, ни maple, поэтому использую связку gnuplot + inkscape + textext. gnuplot'ом рисую графики, inkscap'ом дорабатываю, textext'ом дописываю надписи. Связкой inkscape + textext перерисовываю (оконтуриваю) рисунки, которые не гармонируют с текстом.

iv_vl комментирует...

amorua, спасибо за пост! Из откомментивших, видимо, я один читал полностью пост, поэтому есть придирки. Не понятно, что это за зверь такой, matlabfrag.m, нужно бы дать пояснение:
matlabfrag is a function which exports a Matlab figure to .eps and .tex files for use in LaTeX/pdfLaTeX/LyX. It is inspired by LaPrint, but is intended to be more WYSIWYG, by respecting figure handles better.
То же самое хотелось бы знать про pstool. В своё время, именно из-за подписей я стал искать замену Matlab'у, а ларчик-то открывается совсем просто :) Правда, в последних версиях Matlab был баг: если активировать какую-нибудь панель в рисунке, например, для изменения осей, то размер рисунка меняется и он становится диспропорциональным. Наблюдение за тем, как ты и virens виртуозно владеете Matlab'ом, расширяет границы моего сознания.

@virens комментирует...
я делаю матлабовские скрипты для анализа данных, и записываю данные в текстовые файлы с разметкой (по колонкам).
Вот здесь не понял, а как же MAT-формат, virens? Неужели питон с ним не справляется? Вот же есть.

iv_vl комментирует...

И совсем забыл немного потроллить :)

@virens комментирует...
Они там таки работают, в отличие от хвалёного Дебиана, где CLAPACK выкинут, а LAPACKE положен так, что нихрена не работает.
Гента ждёт тебя, virens! :-P

amorua комментирует...

@infroma:
Для тех, кто любит Python/пользовался Sage рекомендую SageTeX.
Да, согласен, что это возможная альтернатива. Однако, для серьёзных вычислений без больших затрат времени на программирование, к сожалению, у Матлаба на данный момент серьёзных конкурентов нет. Отчасти, это вызвано привычкой. Это, конечно, IMHO.

@virens
я делаю матлабовские скрипты для анализа данных, и записываю данные в текстовые файлы ... Далее на питоне пишется скрипт для генерации многих графиков Gnuplot.
Я раньше тоже так делал, но потом обломался. Сначала перешёл на pdfplots вместо Gnuplot, а потом стал делать всё в Матлабе.
Т.е. один скрипт считает и пишет данные в файл, другой читает данные, строит графики и пишет их в "латех-формате".

@Михаил Саушкин
К сожалению, нет возможности сейчас использовать ни matlab, ни maple
Попробуйте использовать pgfplots. Сначала кажется морочно, но потом, после пары попыток, начинают получаться очень неплохие результаты.

amorua комментирует...

@iv_vl
Из откомментивших, видимо, я один читал полностью пост.
Согласен, пост действительно получился длинноватым. Но хотелось привести детали и подробно их разъяснить.

Не понятно, что это за зверь такой, matlabfrag.m, нужно бы дать пояснение
Может быть вы и правы и стоило это объяснить с самого начала. Однако, я подумал, что желающие учить матчасть пойдут по ссылке (как сделали вы), а нежелающим достаточно рецепта :)
На самом деле, что такое matlabfrag и pstool разъясняется по мере их применения: сразу до и сразу после второго рисунка из этого поста.

virens комментирует...

@iv_vl комментирует...
Из откомментивших, видимо, я один читал полностью пост
Ну, нас по крайней мере двое - я его тоже читал в закрытом блоге :-)
Просто у меня несколько иной workflow.

Наблюдение за тем, как ты и virens виртуозно владеете Matlab
Матлаб это то, в чём постоянно работаешь - там всё сделано для людей и повёрнуто лицом, так что вылазить за его пределы особо нет нужды.

Мои закидоны с гнуплот и графиками объясняются тем, что я знаю, как построить какой-то заковыристый график в гнуплоте - но не знаю, как в матлабе. И потом, часто проще склеить несколько колонок руками (ну, скриптик на bash написать), чем выделываться с матлабовскими plot. Я к gnuplot просто привык - он делает то, что мне надо.

А Матлабу альтернатив нема, это amorua совершенно прав. Хотел посмотреть в сторону IDL/GDL, но едва ли найду там что-нибудь революционное.

Вот здесь не понял, а как же MAT-формат, virens?
Это бинарный проприетарный формат, и мне это не нравится. Текстовые файлы православнее, как ни крути. Их можно анализировать и перегонять во что хочешь - это удобно (на этом месте Леннарту Поттерингу с его бинарными логами предлагается сделать сэпукку :-))

Неужели питон с ним не справляется?
Питон на побегушках справляется хорошо: подтереть за гнуплотом, склеить строчки, выдрать колонку из файла. Чтобы при переходе с питона 2.6 на 3.0 не было мучительно больно за бесцельно прожитые годы :-)


И совсем забыл немного потроллить :)
Гента ждёт тебя, virens! :-P

Конечно! Это ведь то, что мне не хвает именно сейчас - у нас в Австралии тут зима надвигается, а у меня теперь по два ядра аж даже на смартфоне - надо ж конпелять! :-) Заодно и согреюсь...


@amorua комментирует...
Сначала перешёл на pdfplots вместо Gnuplot
Я ленивый дебианщик, у меня "не сломалось - не чини" висит над рабочим столом :-) Вон на старом ноутбуке Etch стоит - и ничего....


@amorua комментирует...
пост действительно получился длинноватым.
А по мне так в самый раз. Тема объёмная, деталей много, и они тут очень хорошо расписаны.

infroma комментирует...

@virens

Хорошо. Так лучше:
кучи библиотек = большого количества написанных однажды библиотек, хорошо выполняющих свою функцию (unix-way).
для тех кто любит Python = для тех, кто не очень разочарован (или не сталкивался) с проблемами с переносимостью (или сталкивался при изучении, но не при переписывании, как я).

Возможно, matlab и круче sage, я не пользовался. Проблема в том, что у меня не столько денег, чтобы покупать matlab за несколько килодолларов (хз сколько, они даже не пишут, пока не зарегишься), для того чтобы использовать малую часть его возможностей. Даже студенческая лицензия за 90$ — не очень дёшево, учитывая что повышенная стипендия в технических вузах меньше — 2500 руб. Тем более, что для моих целей чуть менее, чем полностью хватало Sage. И с целью "вставка графиков в LaTeX" он тоже справляется.

Я думал, что комментарий будет полезным тем, кто ищет как вставлять графики. Ну что же, можете удалить, если вы так не считаете.

Ввязываться в дисскуссию относительно python, sage, matlab и пропиетарного ПО я не буду.

amorua комментирует...

@infoma
Я думал, что комментарий будет полезным тем, кто ищет как вставлять графики. Ну что же, можете удалить, если вы так не считаете.
Комментарий, по-моему, очень даже полезный. Я отнюдь не сторонник использования Матлаба.

С чисто эстетической точки зрения решения на Питоне мне симпатичны. Я очень плохо знаком с Sage, но, например, numpy/scipy выглядят очень прилично (графики они строят через matplotlib).

Но проблема в том, что начиная с определённого момента очень трудно перейти на что-то другое с того к чему уже привык. В западных ВУЗах, на всех естественнонаучных/инженерных специальностях преподают Матлаб (реже Математику). Студенты получают "домашнюю" версию бесплатно, как первую дозу героина. К моменту, когда они устраиваются на работу, привычка столь глубока, что легче приобрести Матлаб (тем более, что контора платит), чем заморачиватьса с чем-то ещё.

virens комментирует...

@infroma комментирует...
кучи библиотек = большого количества написанных однажды библиотек, хорошо выполняющих свою функцию (unix-way).

Мой аргумент был в том, что это именно куча, написанная разными людьми, без полировки и подгонки, и я не уверен, что эта куча будет работать через 3-5-10 лет.

для тех кто любит Python = для тех, кто не очень разочарован (или не сталкивался) с проблемами с переносимостью
Те, кто не сталкивался, просто слишком молоды - но другие об этом в курсе: запрос "python upgrade transition pain in the ass" в Google выдаёт почти миллион совпадений.

Возможно, matlab и круче sage, я не пользовался.
Вопрос не в том, кто круче, вопрос удобства и быстроты разработки. Куча кода в академии пишется в стиле write-once - что-то попробовать, поэкспериментировать и выдать результат. Потом, спустя 10 лет, вдруг требуется это (или часть) ещё раз - и оно должно запуститься.

При всём моём отвращении к ФОРТРАНу, я понимаю, почему им до сих пор пользуются - Legacy.

Проблема в том, что у меня не столько денег, чтобы покупать matlab за несколько килодолларов
infoma, а ты и не должен его покупать - это задача твоего университета обеспечить тебя необходимым инструментарием. То, что кое-где этого не происходит - это отдельный разговор.

Аналогия: представь, что ты работаешь геологом в нефтяной компании. Твоя работа - искать и находить нефть (и другие полезные ископаемые). Тебе нужен профессиональный инструментарий, и задача компании - обеспечить им тебя, ибо от этого зависит успех нахождения нефти. Скажем, нужен экскаватор - значит, компания покупает тебе экскаватор.

Ёпенсорц же предлагает сляпаный в гараже из старых машин каркас (Scilab, например), преставляющий собой пародию на экскаватор. Плюс у него один - бесплатность. Но мне нужен рабочий инструмент, а не пародия на него.

Тем более, что для моих целей чуть менее, чем полностью хватало Sage.
Отлично, я за тебя очень рад. Но для чего-то более серьёзного тебе придётся обмениваться данными с коллегами. Они пришлют тебе MEX-файл - и что ты будешь делать?!

Я думал, что комментарий будет полезным
Комментарий полезен, и, благодаря мне, обладает большим флеймог^W дискуссионным потенциалом :-)

Серьёзно: для профессиональной работы нужен профессиональный инструмент, и это задача работодателя (университет, институт, частная компания) обеспечить тебя хорошим инструментом. Если у них нет денег - значит ни чем серьёзным они не занимаются и не планируют.

И как я уже говорил - Питон мне нравится и я им пользуюсь для скриптов.

amorua комментирует...

@virens
я не уверен, что эта куча будет работать через 3-5-10 лет.
Ты тоже немного утрируешь. Конечно, всегда есть риск, что новая версия что-то сломает. Но опенсорсные проекты страдают этим в гораздо меньшей степени, чем коммерческие. К тому же "базис" Sage'а -- библиотеки с длинной историей и давно устоявшимися API.

Ёпенсорц же предлагает сляпаный в гараже из старых машин каркас (Scilab, например), преставляющий собой пародию на экскаватор. Плюс у него один - бесплатность. Но мне нужен рабочий инструмент, а не пародия на него.
С этим я не согласен. Scilab и octave -- вполне приличные программы, которые подошли бы для выполнения 90% задач. Скажем так, почти всех задач, которые решаются в Матлабе без использования тулбоксов. Другой вопрос, что перелезать с Матлаба на октав (для новых задач) очень не хочется просто, потому что лень.
Аналогичная история, но в гораздо больших масштабах, с, например MSWord и LibreOffice. Для 90% людей разницы между ними никакой, кроме расположения кнопочек. Тем не менее, все орут "верните мне Ворд", просто потому что привыкли.

Но для чего-то более серьёзного тебе придётся обмениваться данными с коллегами. Они пришлют тебе MEX-файл - и что ты будешь делать?!
Ну ты загнул, так загнул! Я тут, судя по репликам участников дискуссии, не самый молодой, но до сих пор данных от коллег в МЕХ-файлах не получал. Вот таблицы по 50Мб в Экселе -- бывает шлют. :)
Но в этом деле горбатого могила исправит -- я обычно отвечаю, что не смог открыть их файл неизвестного мне формата и прошу сохранить в csv. :)

@infroma
Вы меня заинтересовали Sage... Не могли бы вы привести пару примеров. Скажем, проект/задача, над которым/ой вы работаете, какого типа вычисления, и т.п. Было бы интересно на реальный код посмотреть -- насколько он (интуитивно) читаем. Заранее спасибо.

infroma комментирует...

@amorua

Познакомился с Sage для лаб по основам электроники. На них использовался MatCAD, преподаватель сказал, что это не очень хорошо, ибо пропиетарное и сказал, что тот, кто предложит свободную альтернативу и напишет методу, как с ней работать, будет молодец. Ну я написал. Метода (pdf сделанный LibreOffice-ом (эх, намучался тогда с подсветкой и coooder-ом), LaTeX-ом ещё не владел) и сам код с результатами лежат здесь.
https://drive.google.com/folderview?id=0BxSq8zuy41hBaVg1WTFJbk1sSFU&usp=sharing

Можно попробовать Sage (в том числе и загрузить worksheet, выложенный мною) можно здесь: http://www.sagenb.org/ Документация на официальном сайте: http://www.sagemath.org/

Извините, если что не так с физическим смыслом, когда я писал ещё не очень разобрался с диодами. Метода является дополнением к лекционному материалу и служит только для объяснения Sage. Написана с расчётом на то что был 1 семестр программирования на C/Delphi и специальность студента не связана с программированием.

infroma комментирует...

@amorua

Дополнение:
1. Это одна из четырёх лабораторных. Остальные во многом повторяют первую и поэтому неинтересны.
2. Писал не я один, а в общей сложности 4 человека. Но то, что я выложил, преимущественно я.

PS SageTeX позволяет получать картинки непосредственной вставкой в LaTeX питоновского кода (в специальном окружении, конечно).

iv_vl комментирует...

@virens комментирует...
Текстовые файлы православнее, как ни крути. Их можно анализировать и перегонять во что хочешь - это удобно
Гм, согласен. Но я предпочту сначала сделать MAT-файл, если заранее неизвестно, чем данные анализировать и куда перегонять. Перевести в тестовой формат всегда успеется, а double float точность может пригодиться.

При всём моём отвращении к ФОРТРАНу, я понимаю, почему им до сих пор пользуются - Legacy.
Я видел примеры, когда Фортран выбирался не для поддержки legacy, а из-за того, что в университетах есть курсы по нему, а изучать что-либо самостоятельно студенты не берутся. И это, действительно, очень плохо.

infoma, а ты и не должен его покупать - это задача твоего университета обеспечить тебя необходимым инструментарием.
Это ты, virens, хочешь сразу попасть в универ, который бы обеспечил всем необходимым? Такое светит далеко не сразу и далеко не каждому, а делать результат необходимо независимо от места работы.

Скажем, нужен экскаватор - значит, компания покупает тебе экскаватор.
Пример не совсем по делу: у кода нулевые затраты на воспроизводство. Поэтому в перспективе свободный софт лучше: вложившись раз, можно пользоваться неограниченно долго, задачи-то все равно одни и те же. В этом я всячески поддерживаю GSL, аналогов которой в свободном софте нет.

И по графикам: я теоретик и чаще моделирую задачу, чем анализирую экспериментальные данные. Выбрал Asymptote для всего, он единственный позволяет строить качественные 3D схемы и графики, вот мои примеры - вся графика выполнена Asymptote.

amorua комментирует...

@infoma
Мои комплименты -- очень толково написаны обе методички: введение в Сэийдж и лаба.

Надо будет как-то попробовать.

infroma комментирует...

@amorua

Спасибо за одобрение!) Старался. Понял, что писать обучающие пособия — непростое дело.

amorua комментирует...

@iv_vl
вот мои примеры - вся графика выполнена Asymptote.

А почему там все графики растровые? Разве Asymptote не сохраняет в tex-удобоваримом формате?

iv_vl комментирует...

@amorua комментирует...
А почему там все графики растровые?
При количестве точек 200x200 куда целесообразнее использовать растровое изображение, отрисовка векторного могла занимать несколько секунд при гораздо большем объёме файла. Кроме графиков, везде векторные изображения, и даже для 3D.

Разве Asymptote не сохраняет в tex-удобоваримом формате?
Не совсем понимаю, что такое "tex-удобоваримый формат". Можно сохранять векторную графику, например, в EPS, PDF (можно вставить как 3D PRC и вращать картинку внутри PDF), SVG. Вставка в LaTeX-документ - через окружение asy.

iv_vl комментирует...

Забыл добавить: хоть графики растровые, они в формате EPS или PDF.

amorua комментирует...

@iv_vl
хоть графики растровые, они в формате EPS или PDF.
Ну, в каком формате графики не так принципиально. В pdflatex можно было бы вставить и PNG.

Я ради интереса посмотрел на их сайте: похоже, что все графики без цветовых градиентов полностью векторные. С градиентами - растровые, причем растровое всё, включая текст.

iv_vl комментирует...

@amorua комментирует...
С градиентами - растровые, причем растровое всё, включая текст.
Asymptote не только градиенты поддерживает, но и эффект подсветки для трёхмерных изображений. И в одном и другом случае есть выбор между вектором и растром.

amorua комментирует...

@iv_vl
Asymptote не только градиенты поддерживает, но и эффект подсветки для трёхмерных изображений. И в одном и другом случае есть выбор между вектором и растром.
Так в том-то и дело, что, как я понял, если используются градиенты, то Асимптот сохраняет их только как растровые (даже если в "контейнере" eps/pdf)

iv_vl комментирует...

@amorua комментирует...
Так в том-то и дело, что, как я понял, если используются градиенты
Странно видеть недоверие и принятие за болтуна. Но, пожалуй, соглашусь с вами — примеры в галерее Asymptote подобраны неважно. Пробуйте те, что вас заинтересовали, но добавьте в начало файла
settings.render = 0;
или запускайте в командной строке
asy -render 0 <filename>.asy
Я вас уверяю — результатом будет векторное изображение. Поначалу это тоже вводило меня в ступор, а потом разобрался с опциями Asymptote.

amorua комментирует...

@iv_vl
Странно видеть недоверие и принятие за болтуна.
На основе каких моих высказываний вы сделали такие выводы. У меня лично и в мыслях не было. По-моему, у нас с вами шла обычная дискуссия в весьма вежливых тонах.

Я вас уверяю — результатом будет векторное изображение.
Действительно, с опцией "-render 0" получается векторное.
Но что интересно: похоже, что весь текст перегоняется в кривые. Я сначала не мог понять в чём дело: вроде текст есть, а шрифтов нет.

Надо будет запомнить про эту опцию.

iv_vl комментирует...

@amorua комментирует...
Но что интересно: похоже, что весь текст перегоняется в кривые.
Я немного не улавливаю сути. Если двумерная графика - шрифты остаются на своих местах, проверил только что на controlsystem.asy. С трёхмерной графикой сложнее, и сделать общие выводы я не могу. Есть алгоритм векторизации шрифта (PDF, приложение A), если это нужно для преобразования. У меня картина была обратная: если использовать растеризацию для трёхмерных графиков, то подписи на осях тоже превращаются в растр. В связи с этим меня очень заинтересовал ваш пост: можно ли включить в рисунок специальные инструкции, по которым позже добавить на их место текст?

amorua комментирует...

@iv_vl
Я немного не улавливаю сути.
Я никогда не пользовался Асимптот. Что я заметил попробовав несколько примеров из их галереи, с учётом вашего замечание по поводу "-render 0":

- беру asy файл и делаем из него eps и pdf
asy -render 0 near_earth.asy && epstopdf near_earth.eps

- открываю eps файл в любом текстовом редакторе и в его преамбуле ищу шрифты.

- кроме того, открываю pdf файл в evince (или acroread) и либо смотрю в File->Properties->Fonts, либо просто пытаюсь выделить текст мышкой.

Для двумерных графиков, например

buildcycle.pdf controlsystem.pdf image.pdf

шрифты в eps/pdf файле, тект можно выделить.

Для 3-х мерных, хотя текст там не использует никаких 3-хмерных эффектов (поворот и т.п.)

near_earth.pdf xxsq01y.pdf

шрифтов нет, все буковки нарисованы, как кривые Безье.

можно ли включить в рисунок специальные инструкции, по которым позже добавить на их место текст?
Пользуясь методом описанным в этом посте: нет, нельзя.
В теории, если вы руками задаёте координаты местоположения текста, то можно написать wrapper, который будет извлекать их из asy-файла, писать в отдельный тех-файл что-то типа

\begin{picture}(..,..)%
\put(0,0){\includegraphics{drawing.eps или pdf}}%
\put(коорд х, коорд у){\makebox(0,0)[lb]{\smash{ваш текст}}}%
и так далее
\end{picture}%

Как это автоматизировать, я не знаю.
Если очень нужно и графика всего 2-3, можно сделать руками. Рисуете график в asymptote (или в чём-то другом, это не принципиально), но без текста. Затем загружаете его (png или eps или pdf) в inkscape. Там добавляете текст и сохраняете в PDF, как ПДФ+ТеХ. Об этом, кстати, следующий пост из этой серии.

iv_vl комментирует...

@amorua комментирует...
шрифтов нет, все буковки нарисованы, как кривые Безье.
Видимо, алгоритм при "-render 0" страдает некоторыми недостатками и, например, плохо обрабатывает скрытые части поверхности.
Рисуете график в asymptote (или в чём-то другом, это не принципиально), но без текста. Затем загружаете его (png или eps или pdf) в inkscape. Там добавляете текст и сохраняете в PDF, как ПДФ+ТеХ. Об этом, кстати, следующий пост из этой серии.
Так делать не надо. Рисунок в Asymptote нужно строить как обычный двумерный, добавив туда подписи. При этом трёхмерное изображение включается в него в виде двумерной проекции при помощи опции scale. Все реализуется в пределах одного asy-файла.

amorua комментирует...

@iv_vl комментирует..
Рисунок в Asymptote нужно строить как обычный двумерный, добавив туда подписи. При этом трёхмерное изображение включается в него в виде двумерной проекции при помощи опции scale.
Или так... Я имел в виду, что философия такова: отдельно рисуем, потом куда-то вставляем и добавляем текст.

Забавная штука asymptote, мне нравится.
Не подскажете, так в галерее есть пример, где читается большой массив данных, а потом что-то делается с его элементами и строится 2-мерный график с несколькими у-осями?
Заранее спасибо.

iv_vl комментирует...

@amorua комментирует...
Не подскажете, так в галерее есть пример, где читается большой массив данных, а потом что-то делается с его элементами и строится 2-мерный график с несколькими у-осями?
Не интересовался этим, но, помимо основной галереи, есть еще другая. Раз ваша цель графики, то рекомендую сначала посмотреть на специальные программы, например, MathGL. У Asymptote богатый выбор примитивов, любой график сделать можно, но по затратам времени это может быть невыгодно.

virens комментирует...

Ну ничего себе вы тут парламент развели, товарищи! :-) Asymptote у них тут, перебранки и разве что тараканы дрессированные графики не строят! Я уж подумал, что спамеры в этом посте устроили брусиловский прорыв...

Про Asymptote не знаю, так как не использовал - мне не надо сексапильные кривые строить, а надо обсчитывать экспериментальные данные или результаты симуляций. Но почитать было интересно.

@iv_vl
Раз ваша цель графики, то рекомендую сначала посмотреть на специальные программы, например, MathGL.
Графики бывают разные. Мне тут вот один фортранщик зело нахваливает matplotlib. На мой вопрос "а чем оно лучше гнуплота" выдаёт какое-то мычание про то, что оно на питоне и вообще так теперь носють :-)

Не мог бы тов. iv_vl пояснить простым колхозникам, зачем оно, MathGL, надо? Из ихнего убогого сайта можно выцедить только:

MathGL drawing can be created not only by object oriented languages (like, C++ or Python), but also by pure C or Fortran-like languages.

Т.е., насколько я понял, если кому-то на C\Фортране приспичило показать картинку, то MathGL это самое оно. А как быть, если нужно просто построить график, без заездов в Си или Фортран?

Да, пока трол^W участники дискуссии ещё не разбежались: что такого модного есть в matplotlib (кроме питона), чего нет в гнуплот?

amorua комментирует...

@virens
что такого модного есть в matplotlib (кроме питона), чего нет в гнуплот?

Ничего. Просто он на Питоне, и люди пользующиеся numpy/scipy предпочитают его. Оно и понятно: так же как мне лень вылезать из Матлаба, чтобы построить график в гнуплоте, так же им в лом оставлять обжитый уже Питон.

amorua комментирует...

@virens
зачем оно, MathGL, надо?
можешь у самого автора спросить: он (раньше, по крайней мере) постоянно на ЛоРе светился. У него год назад брали интервью
http://www.floss4science.com/interview-mathgl/

Анонимный комментирует...

Подскажите, пожалуйста, уже замучался. У меня windows ввожу в командную строку "pdflatex -shell-escape имя-тех-файла" пишет, что не может найти файл.

amorua комментирует...

@Анонимный комментирует
"pdflatex -shell-escape имя-тех-файла" пишет, что не может найти файл.

Из вашего вопроса непонятно, что он не может найти: Латех или документ

1. Если просто pdflatex набрать, то он находит сам Латех? Если нет, убедитесь что он в путях

2. Если он не может найти тех файл, убедитесь, что файл именно в той директории, где вы запускаете Латех. Например, если тех-файл в d:\Mydocs\qaz\myfile.tex, то делаете так (после открытия командной строки):

d: и жмете Enter
cd Mydocs\qaz
pdflatex -shell-escape myfile.tex

Анонимный комментирует...

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

Максим К комментирует...

Спасибо большее за очень полезную статью! У меня возникла проблема, когда я пишу текст на русском на графике в matlab, то его не видно. После компелирования latex файла, в готовом документе на местах картинок пусто. Когда тест на английском то все нормально. Как заставить matlab отображать текст в интерпретаторе latex. Matlab установлен на windows и mac os, проблема одинаковая на обоих системах.

V_oron комментирует...

amorua, хочу сделать примечание к matlabfrag.m. Пришлось внести такие изменения:

$ diff matlabfrag.m matlabfrag-amorua.m
225,233d224
<
< figChild = get(p.Results.handle, 'Children'); %findobj(p.Results.handle,'Type','axes');
< for ii = 1:length(figChild)
< if strcmpi(get(figChild(ii),'tag'), 'legend')
< figChild_legend_ii = ii;
< figChild_init_units = get(figChild(ii),'Units');
< set(figChild(ii),'Units', get(p.Results.handle,'PaperUnits'))
< end
< end
235,236d225
< set(figChild(figChild_legend_ii),'Units', figChild_init_units)
<

То есть, поле Units у легенды надо сделать таким же, как у графика -- и там и там сантиметры. Без этого при создании eps-файла у меня размер легенды становился очень большим: конвертор использует сантиметры, когда сама легенда в "нормальных единицах".

Aram Malkhasyan комментирует...

У меня две проблемы

1. Использую LyX. Когда я добавляю строку \psfragfig{figs/example1} и пытаюсь скомпилировать файл, появляется ошибка

\psfragfig
{figs/example1}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

2. Когда я пытаюсь просто экспортировать из Матлаба графики с помощью saveas - подписи к осям неправильно декодируются. Те матлабовская функция SaveAs не понимает русскую кодировку.

В чем здесь может быть проблема?

Спасибо

Отправить комментарий

Подписаться на RSS-ленту комментариев к этому посту.