MATLAB.Exponenta
–Û·Ë͇ Matlab&Toolboxes

Приложения с GUI и дескрипторная графика

Дескрипторная графика

Рисованные объекты

В MATLAB 7.0 появилось новшество по сравнению с предыдущими версиями. Если в версиях 6.x функция plot и подобные ей создавали объект линию (Line), то в 7-ой версии эти функции создают рисованный объект (Plot Object), который называется Lineseries. В 7-ой версии MATLAB объект Line есть, но он отнесен к базовым объектам (Core Objects), которые создаются низкоуровневыми графическими функциями, в частности line, surface и т. д.

Рисованные объекты обладают рядом специальных свойств, которые позволяют быстро настроить вид объекта и не обращаться к составляющим его низкоуровневым объектам.

Названия рисованных объектов связаны с соответствующими высокоуровневыми графическими функциями. К рисованным объектам относятся:

· Areaseries - строится в результате работы функции area.

· Barseries - строится в результате работы функций bar, barh.

· Contourgroup - строится в результате работы функции contour.

· Errorbarseries - строится в результате работы функции errorbar.

· Lineseries - строится в результате работы функций plot, plot3, semilogx, semilogy и plotyy.

· Quivergroup - строится в результате работы функций quiver и quiver3.

· Scattergroup - строится в результате работы функций scatter и scatter3.

· Stairseries - строится в результате работы функции stairs.

· Stemseries - строится в результате работы функций stem and stem3.

· Surfaceplot - строится в результате работы функций surf, surfc, mesh, meshc и meshz.

В справочной системе MATLAB описанию рисованных объектов посвящен раздел Graphics: Handle Graphics Objects: Plot Objects. Для быстрого доступа к свойствам рисованных объектов удобно пользоваться браузером свойств, который находится в разделе Handle Graphics Property Browser.

Совместимость с версиями MATLAB 6.x

Для совместимости с версиями MATLAB 6.x имеется возможность отказаться от создания рисованного объекта и получить вместо него один из базовых. Для этого следует вызвать соответствующую высокоуровневую графическую функцию с первым входным аргументом 'v6', например:

h = plot(x, y)

создает рисованный объект Lineseries и записывает указатель на него в переменную h, а

h = plot('v6', x, y)

создает базовый объект Line и записывает указатель на него в переменную h.

Если графическое окно сохраняется в MATLAB 7 и планируется его использование в предыдущих версиях, то необходимо выполнить следующие действия.

1. Надо вызывать высокоуровневые графические функции, которые строят рисованные графические объекты, с аргументом 'v6'.

2. Перед сохранением графического окна необходимо задать совместимость. Это можно сделать, выбрав в меню File пункт Preferences (в рабочей среде или графическом окне). Появляется диалоговое окно Preferences, в котором следует в левой части выбрать раздел General: MAT-files и в правой части (см. рис. 1) установить переключатель Ensure backward compatibility (-v6). Если для сохранения графического окна применяется функция hgsave, то ее последним входным аргументом должен быть '-v6' (при этом переключатель в окне Preferences может быть и в положении Use defaulf features), например:

hF = figure;

bar('v6', [1,2,3])

hgsave(hF, 'barplot', '-v6')

Рис. 1. Задание опции совместимости с версиями MATLAB 6.x

Свойства линий

В этом разделе мы рассмотрим основные свойства линий - рисованных графических объектов Lineseries, которые создаются такими высокоуровневыми функциями, как plot, plot3, semilogx, semilogy, plotyy.

Свойства рисованного объекта Lineseries и базового объекта Line практически совпадают, поэтому мы сначала рассмотрим их общие свойства, а потом свойства, специфичные для объекта Lineseries.

Цвет, толщина, тип линии, маркеры, скрытие линии

За эти характеристики линии отвечают следующие свойства:

· Color - цвет линии. Значения: один из предопределенных цветов 'r', 'g' и т.д. или цвет в формате RGB.

· LineWidth - толщина линии в пунктах (1 пт. = 1/72 дюйма). По умолчанию 0.5 пт.

· LineStyle - тип линии. Значения: один из предопределенных типов линии (сплошная по умолчанию).

· Marker - тип маркера. Значения: один из предопределенных типов маркера (по умолчанию маркер не ставится).

· MarkerEdgeColor - цвет границы маркера. Значения: один из предопределенных цветов 'r', 'g' и т.д. или цвет в формате RGB.

· MarkerFaceColor - цвет внутренности маркера. Значения: один из предопределенных цветов 'r', 'g' и т.д. или цвет в формате RGB. Задается только для тех маркеров, у которых есть внутренность: кружок, треугольники, ромб, квадрат, пяти- и шестиконечная звезда.

· MarkerSize - размер маркера в пунктах (1 пт. = 1/72 дюйма). По умолчанию 6 пт. Для маркера-точки берется 1/3 от указанного размера.

· Visible - отображение линии. Значения: 'on' (по умолчанию линия видна) или 'off' (линия не видна).

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

x = 0:pi/10:2*pi;

f = cos(x);

plot(x, f, 'Color', 'r', 'LineWidth' ,2, 'Marker', 'p',...

    'MarkerSize', 14, 'MarkerEdgeColor', 'g', 'MarkerFaceColor', 'y')

Рис. 1. Пример изменения свойств линии

В этом примере мы применили способ вызова высокоуровневой функции plot, который позволяет задать свойства объекта Lineseries во входных аргументах. Можно было вызвать plot с выходным аргументом - указателем на объект Lineseries - а затем установить его свойства в подходящие значения при помощи set, результат будет аналогичный:

hL = plot(x, f)

set(hL, 'Color', 'r', 'LineWidth' ,2, 'Marker', 'p',...

    'MarkerSize', 14, 'MarkerEdgeColor', 'g', 'MarkerFaceColor', 'y')

Если функция plot используется для одновременного построения нескольких линий графиков, то без указателей не обойтись. В этом случае выходной аргумент plot является вектором, каждый элемент которого содержит указатель на соответствующий объект Lineseries (см. результат на рис. 2):

x = 0:pi/10:2*pi;

f = cos(x);

g = sin(x);

hL = plot(x,f,x,g);

set(hL(1), 'Color', 'g', 'LineWidth', 2, 'Marker', '<', ...

    'MarkerSize', 14, 'MarkerEdgeColor', 'k', 'MarkerFaceColor', 'y')

set(hL(2), 'Color', 'm', 'LineWidth', 16, 'LineStyle', ':')

Примечание.

Можно, конечно, нарисовать линии по отдельности: сначала первую, потом выполнить hold on, потом добавить вторую.

Рис. 2. Изменение свойств двух линий.

Следует отметить два обстоятельства:

1) толщина границы маркера совпадает с толщиной линии;

2) координаты маркеров совпадают с координатами точек для построения графиков, заданных массивами.

Это не всегда удобно, особенно если для построения графика следует использовать достаточно много точек. Например, построим график функции на отрезке и разметим его круглыми маркерами:

x = 0:pi/200:2*pi;

y = sin(x.^2);

plot(x, y, 'LineWidth', 2, 'Marker', 'o', 'MarkerSize', 8)

Получим достаточно много маркеров (см. рис. 3 слева). Можно поступить и по-другому - построить отдельно график только линией, а для более редкого набора значений аргумента вывести график этой же функции одними маркерами. Получим тогда два объекта Lineseries и распорядимся их свойствами (см. рис. 3 справа):

x = 0:pi/200:2*pi;

y = sin(x.^2);

% построение двух графиков заданной функции

% с разными наборами значений аргумента

hL = plot(x, y, x(1:10:end), y(1:10:end))

% задание общих свойств (толщины линии и цвета) двум объектам Lineseries

set(hL, 'LineWidth', 2, 'Color', 'b')

% задание свойств второму объекту Lineseries (его рисуем только маркерами)

set(hL(2), 'LineStyle', 'none', 'Marker', 'o', 'MarkerSize', 8)

Рис. 3. Размещение маркеров в заданных позициях

Для того, чтобы сделать линию невидимой, недостаточно нарисовать ее белым цветом, или изменить ее цвет на белый. Во-первых, цвет фона осей может быть отличным от белого, а во-вторых, она может перекрыть имеющиеся объекты. Поэтому, для скрытия линии обращаются к ее свойству Visible и устанавливают его в 'off'. Для отображения линии достаточно вернуть значение 'on', которое задается по умолчанию.

Все вышесказанное справедливо и для функций plot3, semilogx, semilogy, plotyy. Следует иметь ввиду, что функция plotyy создает две пары осей и две линии. Обращение к ней с выходными аргументами выглядит следующим образом:

[hA, hL1, hL2] = plotyy(x1, y1, x2, y2)

где: hA - вектор указателей на пары осей; hL1 - указатель на линию, соответствующую паре x1, y1; hL2 - указатель на линию, соответствующую паре x2, y2.

Перекрытие линий

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

Итак, создаем графическое окно и рисуем две линии

>> figure

>> hL1 = plot([1 2], [1 2], 'LineWidth', 20, 'Color', 'r')

>> hold on

>> hL2 = plot([1 2], [2 1], 'LineWidth', 20, 'Color', 'g')

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

>> hA = get(hL1, 'Parent')

и задаем нужный порядок их потомков

>> set(hA, 'Children', [hL1 hL2])

В результате перекрытие линий изменяется (см. рис. 4 справа).

Рис. 4. Изменения порядка перекрытия объектов (линий)

Изменение данных

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

1. Удалить линию и построить новую. При этом объект Lineseries удалится и создастся новый со своим указателем.

2. Прибегнуть к свойствам XData, YData (и ZData в трехмерном случае) существующей линии. Свойства XData, YData и ZData должны содержать массивы со значениями абсцисс, ординат и аппликат. Объект Lineseries обновится, останется и будет иметь тот же самый указатель.

Рассмотрим второй способ. Построим окружность:

>> t = 0:pi/20:2*pi;

>> x = sin(t);

>> y = cos(t);

>> hL = plot(x, y);

а затем изменим данные для получения астроиды:

>> x = sin(t).^3;

>> y = cos(t).^3;

и установим свойства XData и YData линии в нужные значения:

>> set(hL, 'XData', x, 'YData', y)

График изменился (см. рис. 5). Более того, можно сделать линию трехмерной, задав ZData (см. рис. 5):

>> x = sin(2*t);

>> y = cos(2*t);

>> z = t;

>> set(hL, 'XData', x, 'YData', y, 'ZData', z)

>> view(3)

Рис. 5. Изменение свойств линии XData, YData и ZData

Свойства, специфичные для рисованного объекта Lineseries

В этом разделе мы рассмотрим свойства, которые имеются у рисованного объекта Lineseries и отсутствуют у базового объекта Line:

· XDataSource, YDataSource, ZDataSource - ассоциирование данных (для построения линии) с переменными. После изменения значения переменных можно обновить график при помощи функции refreshdata.

· DisplayName - присвоение имени объекту Lineseries, которое будет отображаться в легенде.

Следующий пример файл-программы демонстрирует использование свойств XDataSource и YDataSource (свойство ZDataSource применяется аналогично). При создании линии, свойства XDataSource и YDataSource принимают значения имен переменных. Их изменение приводит к перестроению линии. Сама линия (как объект) остается и указатель на нее не меняется. Очевидно, что при этом изменяются значения свойств XData и YData, рассмотренных в предыдущем разделе.

x = 0:0.01:5;

y = sin(x);

hL = plot(x, y, 'XDataSource', 'x', 'YDataSource', 'y')

pause(0.5)

for k=1:7

    y = sin(k*x);

    refreshdata(hL)

    pause(0.5)

end

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

При обращении к свойствам XDataSource, YDataSource и ZDataSource с последующим вызовом функции refreshdata следует учитывать, что по умолчанию refreshdata берет глобальные переменные рабочей среды в качестве массивов с данными (в нашем примере - массивы x и y). Поэтому, если приведенный выше пример оформить в файл-функции, например myplot, то работать она не будет, поскольку переменные файл-функции являются локальными.

function myplot

x = 0:0.01:5;

y = sin(x);

hL = plot(x, y, 'XDataSource', 'x', 'YDataSource', 'y')

pause(0.5)

for k=1:7

    y = sin(k*x);

    refreshdata(hL)

    pause(0.5)

end

Возможно два варианта.

1. В рабочей среде есть массивы с именами x и y, тогда они будут использоваться при каждом вызове функции refreshdata, очевидно, без обновления графика.

2. В рабочей среде нет массивов с именами x и y, тогда при каждом обращении к refreshdata выводится предупреждение:

Warning: Could not refresh XData from 'x'.

> In refreshdata at 54

  In myplot at 8

Warning: Could not refresh YData from 'y'.

> In refreshdata at 54

In myplot at 8

Выход заключается в правильном обращении к функции refreshdata - с двумя входными аргументами. Первый из них должен быть указателем на графический объект, а второй - строкой 'caller'. Т.е. в файл-функции следовало бы указать refreshdata(hL, 'caller').

Стоит обратить внимание еще на одно обстоятельство. В нашем примере для задержки использована функция pause со входным аргументом - временем в секундах. Если убрать обращение к pause, то мы увидим только самый первый и последний график. Так происходит потому, что MATLAB сначала выполняет все события в очереди, а потом перерисовывает графическое окно. Для приостановки выполнения событий из очереди и немедленного обновления графического окна служит функция drawnow, которую следует вызывать после команд графического вывода или обновления графических объектов. Вот соответствующий пример:

function myplot2

x = 0:0.01:5;

y = sin(x);

hL = plot(x, y, 'XDataSource', 'x', 'YDataSource', 'y')

drawnow

for k=1:100

    y = sin(k*x);

    refreshdata(hL)

    drawnow

end

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

>> x = 0:pi/30:2*pi;

>> f = exp(-x).*cos(x);

>> g = exp(-x).*sin(x);

>> hL1 = plot(x, f, 'DisplayName', '{\ite}^{-\itx}cos{\itx}', 'Color', 'r')

>> hold on

>> hL2 = plot(x, g, 'DisplayName', '{\ite}^{-\itx}sin{\itx}', 'Color', 'g')

>> legend('show')

Рис. 6. Использование свойства DisplayName объекта Lineseries

Заметьте, что при изменении значения свойства DisplayName автоматически происходит обновление легенды:

>> set(hL1, 'DisplayName', '1-st component')

>> set(hL2, 'DisplayName', '2-nd component')


Поиск по сайту:

Система Orphus

Яндекс.Метрика