Scilab/Графики

Материал из Викиучебника — открытых книг для открытого мира

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

Основные понятия[править]

Для начала определим то, с чем мы будем иметь дело. График — это графическое представление функции. В среде Scilab все графики строятся по точкам, при этом каждые две соседние точки соединяются друг с другом отрезком. Чем меньше расстояние между точками, тем меньше искажение графика за счет замены его реального образа кусочно-линейной функцией. К сожалению, координаты точек нужно где-то хранить, что является главным ограничивающим фактором в желании получить как можно более плавное представление.

Внешний вид графика определяют следующие факторы:

  • Математическая функция и система координат:
    • двухмерный график — график функции с одним аргументом, либо, если функция представлена неявно, одномерной функции;
      • в прямоугольной системе координат;
      • в полярной системе координат;
      • в комплексной плоскости (например, годографы);
      • в векторной плоскости;
    • трехмерный график — график функции с двумя аргументами, либо, если функция представлена неявно, двухмерной функции;
      • в пространственной прямоугольной системе координат;
      • в сферической системе координат;
      • в цилиндрической системе координат;
      • в векторном пространстве.
  • Способ представления:
    • точечный график;
    • линейный график (с учетом всевозможных представлений линии);
    • полигональный график;
    • градиентный график;
    • контурный график
    • гистограмма.

Все графики в Scilab строятся в так называемых графических окнах (англ. Figure). Графические окна используются не только для построения графиков, но и для создания пользовательских интерфейсов, анимации и рисования, о чем подробнее будет рассказано в другом разделе. Каждое графическое окно имеет идентификатор, который называется дескриптором графического окна или просто дескриптором (англ. Handle), когда опускание уточнения не вводит в заблуждение. В дальнейшем вы увидите, что дескриптор есть не только у графических окон.

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

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

Создание графического окна[править]

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

scf(num)
// num — необязательный параметр, задающий номер окна

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

Давайте попробуем создать графическое окно

-->scf()
ans  =
 
Handle of type "Figure" with properties:
========================================
children: "Axes"
figure_position = [200,200]
figure_size = [626,580]
axes_size = [610,460]
auto_resize = "on"
viewport = [0,0]
figure_name = "Графическое окно %d"
figure_id = 0
info_message = ""
color_map = matrix 32x3
pixmap = "off"
pixel_drawing_mode = "copy"
anti_aliasing = "off"
immediate_drawing = "on"
background =  -2
visible = "on"
rotation_style = "unary"
event_handler = ""
event_handler_enable = "off"
user_data = []
resizefcn = ""
closerequestfcn = ""
tag = ""

После вызова функции появится графическое окно с номером 0, а в командном окне вы увидите параметры данного окна.

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

Давайте создадим еще одно графическое окно, но определим его номер самостоятельно. Для этого введем команду

-->scf(5);

Теперь у нас два графических окна под номерами 0 и 5, текущим из которых является окно 5. Чтобы посмотреть весь перечень открытых окон, необходимо вызвать макрос

-->winsid
 ans  =
    0.    5.

который вернет вектор с номерами всех открытых графических окон. Давайте снова сделаем активным окно 0, для чего вызовем функцию scf()

-->scf(0);

Закрыть графическое окно можно двумя способами:

  • Нажать на «крестик» в верхнем правом углу окна, при этом дескриптор окна удалится автоматически;
  • Воспользоваться функцией xdel(), которой необходимо передать вектор номеров всех графических окон, которые вы желаете закрыть.

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

-->xdel(5), winsid
 ans  =
    0.

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

Построение графиков[править]

Любой график имеет следующие элементы:

  1. Собственно сам график функции (один или несколько), включая параметры его отображения;
  2. Оси системы координат, включая внешний вид, масштаб отсчета и подписи осей;
  3. Координатная сетка;
  4. Подпись графика;
  5. Легенда;
  6. Надписи на самом графике.

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

Построение графиков одномерных функций[править]

Как было сказано ранее, все графики строятся по точкам, а сам массив точек иногда называют точечной функцией. У одномерной функции точка характеризуется двумя координатами — значением аргумента и значением функции. Обычно множество значений аргумента и функции записываются в векторы, которые передаются уже в качестве аргументов для строящих функций.

Для построения одномерных функций в прямоугольной системе координат служат следующие функции:

  • семейство функций plot2d*(), выполняющих построение по точечной функции, где символ звездочки кодирует заранее определенный шаблон:
    • plot2d — строит график по форматам, определяемым пользователем;
    • plot2d2 — строит график в виде ступенчатой функции;
    • plot2d3 — строит график в виде вертикальных полосок;
    • plot2d4 — строит график с указанием направления;
  • Функция fplot2d(), выполняющая построение по заранее определенной функции;
  • Функция plot(); подробнее рассмотрена в конце главы (является полным аналогом семейства plot2d и служит для совместимости с MATLAB).
Упражнение

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

-->deff('y=f(x)','y=x^2');

Теперь нам нужны точки. Для примера определим два вектора в один из которых мы запишем значения аргументов в диапазоне от -10 до 10, а во второй вектор — значения функции от этих аргументов.

-->X=-10:10;
-->Y=f(X);

Самый простой вызов функции plot2d() заключается в передаче именно этих векторов в качестве аргументов. Если до этого ни одного графического окна не было создано, то оно будет создано автоматически. Вызовите функцию

-->plot2d(X,Y)

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

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

-->plot2d(X,X.^3)

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

Сделайте активным графическое окно. Затем попробуйте покрутить колесико мыши. Таким образом, вы можете управлять масштабом в пределах множества определенных заранее аргументов. Если вы зажмете левую кнопку мыши и попробуете перетащить курсор, то увидите как передвигается область. При этом оси перестраиваются автоматически.

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

Рисование графика — сложный процесс, который заключается в создании объектов в понимании объектно-ориентированного программирования. Например, сначала было создано графическое окно «Figure» (объект), которое затем породило потомков (англ. Children) «Axes» (оси, которые вы видите на экране). У осей тоже есть потомки и это как раз сами линии графика, которые к ним привязываются.

Любой объект в Scilab является типизованным списком, указатель на который мы и называем дескриптором. Для извлечения параметров графических объектов служит функция get(). Для примера, давайте посмотрим сколько потомков у наших осей

-->get("current_axes") 
 ans  =
 
Handle of type "Axes" with properties:
======================================
parent: Figure
children: ["Compound","Compound"]
 
visible = "on"
axes_visible = ["on","on","on"]
axes_reverse = ["off","off","off"]
grid = [-1,-1]
grid_position = "background"
grid_thickness = [1,1]
grid_style = [3,3]
x_location = "bottom"
y_location = "left"
title: "Label"
x_label: "Label"
y_label: "Label"
z_label: "Label"
auto_ticks = ["on","on","on"]
x_ticks.locations = matrix 11x1
y_ticks.locations = matrix 11x1
z_ticks.locations = []
x_ticks.labels = matrix 11x1
y_ticks.labels = matrix 11x1
z_ticks.labels = []
ticks_format = ["","",""]
ticks_st = [1,1,1;0,0,0]
box = "off"
filled = "on"
sub_ticks = [1,1]
font_style = 6
font_size = 1
font_color = -1
fractional_font = "off"
 
isoview = "off"
cube_scaling = "off"
view = "2d"
rotation_angles = [0,270]
log_flags = "nnn"
tight_limits = "off"
data_bounds = [-10,-1000;10,1000]
zoom_box = []
margins = [0.125,0.125,0.125,0.125]
auto_margins = "on"
axes_bounds = [0,0,1,1]
 
auto_clear = "off"
auto_scale = "on"
 
hidden_axis_color = 4
hiddencolor = 4
line_mode = "on"
line_style = 1
thickness = 1
mark_mode = "off"
mark_style = 0
mark_size_unit = "tabulated"
mark_size = 0
mark_foreground = -1
mark_background = -2
foreground = -1
background = -2
arc_drawing_method = "lines"
clip_state = "clipgrf"
clip_box = []
user_data = []
tag =

В данном примере функция вернула дескриптор осей текущего графического окна с полным перечнем свойств. Мы можем наблюдать, что оси текущего графического окна имеют два потомка, отраженных в строке children. Чтобы удалить потомков, а следовательно стереть график, необходимо воспользоваться функцией delete(). Давайте удалим график параболы, для чего нужно просто правильно передать дескриптор интересующего нас объекта.

//запишем дескриптор осей в отдельную переменную
-->a=get('current_axes');
//теперь найдем потомков
-->a.children
 ans  =
 
2 by 1 matrix of handles:
=========================
Compound 
Compound 
//то, что мы нашли, дескрипторы для наших графиков. Удалим параболу
-->delete(a.children(2))

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

-->a.children
 ans  =
 
Handle of type "Compound" with properties:
==========================================
parent: Axes
children: "Polyline"
visible = "on"
user_data = []
tag =

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

Самостоятельно

Теперь предлагаем читателю самостоятельно построить график с помощью функции fplot2d(). Напомним, что ей не нужны сами координаты, а нужна формула, по которой значения функции будут рассчитаны. Это удобно, когда вы работаете не с экспериментальными данными, где обычно имеют дело с точечными функциями, а с аналитически определенными функциями. Чтобы функция fplot2d() сработала, ей нужно передать два аргумента: вектор значений аргумента и имя заранее определенной функции (без аргументов).

В рамках данного упражнения, выполните следующие шаги:

  1. Закройте все графические окна, если они есть.
  2. Создайте графическое окно.
  3. Обратитесь к свойству figure_name созданного вами окна (помните что дескриптор сохраняется в ans) и присвойте ему новое значение 'Мое графическое окно'. Найдите в самом окне изменения.
  4. Объявите функцию
  5. Постройте график функции с помощью fplot2d() на множестве от 1 до 10 с шагом 0,1.
  6. Создайте второе графическое окно и выполните процедуру из предыдущего пункта, но с шагом 1.
  7. Запишите дескриптор текущего окна в переменную и сделайте вновь активным графическое окно с номером 0.
  8. Теперь через полученный дескриптор из предыдущего пункта очистите графическое окно 1 от графика и осей (помните, что оси это потомки графического окна).
  9. Закройте программно все графические окна за один вызов.

Для построения графиков в полярной системе координат служит функция polarplot(). Полный прототип функции выглядит так

polarplot(theta,rho,[style,strf,leg,rect])
// theta — азимут
// rho — радиальная координата
// [style,strf,leg,rect] — настройки внешнего вида (рассмотрены ниже)

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

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

Самостоятельно

Опираясь на предыдущий материал самостоятельно постройте графики показанные на рисунке.

Двумерное построение графиков[править]

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

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

Полный прототип функции plot2d() имеет следующий вид (квадратные скобки означают необязательные аргументы или флаги)

plot2d([logflag,][x,],y[,style[,strf[,leg[,rect[,nax]]]]])
// logflag — флаг, который включает логарифмический масштаб для осей;
// style — позволяет управлять цветом, либо включает точечное отображение графика;
// strf — управление отображением некоторых элементов; строка из трех цифр-символов;
// leg — задает надписи легенды;
// rect — устанавливает видимыми границами графика;
// nax — управляет видимыми на оси делениями;
// Неявные флаги — отдельное обращение к двум последним символам strf
// frameflag — показывает построителю как размещать графики относительно осей
// axesflag — настраивает стиль осей

Здесь мы отметим, что некоторые параметры имеют большое количество возможных значений, что порождает еще большее количество возможных комбинаций. Обычное их перечисление здесь не поспособствует быстрого освоения ими, поэтому мы рекомендуем вам поэкспериментировать самостоятельно со всеми этими параметрами. Для начала мы приведем несколько поучительных примеров. Возможные значения этих параметров мы специально вынесли в приложение к учебнику. Также вы всегда можете воспользоваться справкой Scilab, воспользовавшись командой help.

Пример 1
Постройте график функции синуса в диапазоне от 1 до 4π со следующими параметрами:

  • цвет графика — синий
  • стиль линии — штрих-пунктир
  • сетка — включена
  • легенда — включена
  • подпись графика — имеет надпись "Мой график"
  • подписи осей — имеют надписи "Ось абсцисс" и "Ось ординат" соответственно
// вызов функции plot2d будет таким
-->x=1:0.1:4*%pi;
-->plot2d( x, ..                        // диапазон аргументов 
           sin(x),      ..              // функция
           style = color('blue'), ..    // задает синий цвет линии
           leg = 'Функция синуса', ..   // задает надпись легенды
           strf='181')                  // цифра 1 включает рамочки с подписями, в том числе легенду
                                        // цифра 8 — построитель размещает график по границам диапазона значений
                                        // цифра 1 — оси рисуются слева
// Все остальное включается вручную через дескриптор
-->g=get('current_axes');               // получаем дескриптор осей
-->g.title.text='Мой график';           // делаем подпись графика
-->g.x_label.text='Ось абсцисс';        // делаем подпись для оси абсцисс
-->g.y_label.text='Ось ординат';        // делаем подпись для оси ординат
-->g.children(1).children.line_style=6; // меняем стиль линии на штрих-пунктирный
-->g.grid=[0 0];                        // включаем сетку и делаем её черной
-->g.children(1).children.thickness=4;  // делаем линию чуть-чуть потолще
На рисунке вы видите результат примера 1. Очевидно, что подписи с установками по умолчанию мелковаты, однако их размеры тоже можно увеличить с помощью все того же дескриптора

Если все сделано правильно, то вы должны увидеть результат показанный на рисунке. Обратите внимание на то, что у осей два потомка: график и легенда. Именно поэтому при обращении к потомкам осей мы указали индекс, указывающий на график. Функция color() возвращает внутренний код цвета по его имени или RGB коду (color(r,g,b)). Никакой ошибки не будет, если ввести код сразу, например, для синего это 2.

На «своей шкуре» вы только что почувствовали как это трудоемко производить настройку вручную. К счастью, разработчики подумали о пользователе и внедрили в среду графический редактор (англ. Graphic Editor), который сам обращается ко всем параметрам. Пользователю же нужно просто правильно выбрать параметр и ввести в поле значение. Окно редактора строится также как и любое графическое окно с помощью интерфейса Tcl/Tk. Данный интерфейс поддерживается только в версиях для Windows и Unix-подобных систем, т.е. пользователи Mac OS не смогут воспользоваться редактором. В будущей версии 6 разработчики обещали исправить это недоразумение.

Чтобы открыть редактор нужно:

  1. Сделать активным интересующее вас графическое окно;
  2. В раскрывающемся меню Правка выбрать пункт Свойства осей….

После этого откроется окно редактора в котором вы увидите слева дерево объектов данного графического окна. Переключаясь по пунктам этого дерева вы будете видеть справа параметры этого окна. Некоторые из них вводятся в поля, некоторые переключаются с помощью ползунков, а некоторые имеют раскрывающееся меню. Если вы не знаете, что делает тот или иной параметр, вы можете поэкспериментировать, так как результат меняется на ваших глазах. Следует помнить, что подписи в окне могут не соответствовать истинным названиям параметров в самом типизованном списке класса.

Пример 2
Построить одновременно графики параболы и кубической параболы разными цветами на множестве от -10 до 10. Настроить разлиновку осей так, чтобы между двумя крупными делениями было 4 маленьких. Оси расчертить крест-накрест

-->x=[-10:0.1:10]';                // при передаче нескольких функций сразу, принципиально важно представлять вектор столбцом,
                                   // иначе функция сработает неправильно
-->plot2d( x, ..
           [x.^2,x.^3], ..         // за один вызов мы можем передавать в векторе несколько функций
           [5,6], ..               // если не указано имя параметра, то функция «предполагает» сначала, что это style
                                   // в векторе должно быть столько же значений, сколько и функций. Числа взяты случайно
           nax = [4,10,4,10], ..   // первые два числа для оси OX, а вторые — OY. Первое число указывает на число мелких 
                                   // рисок между крупными
                                   // Второе число указывает на число крупных рисок оси
           axesflag = 5)           // число 5 указывает на перекрестный стиль осей
Результат вызова функции из примера 2. Очевидно число 5 кодирует красный цвет, а 6 — фиолетовый. Также видно, что выбранные нами настройки сетки неудачные, так как нарушена эстетическая красота. Настраивать оси лучше через графический редактор

Действия над графиками[править]

Как вы уже знаете, все функции-построители, вызванные в командном окне, будут рисовать в текущем графическом окне. Это означает, что все объекты, которые будут ими создаваться, будут накладываться поверх уже созданных. Для удаления объектов в графическом окне служит функция delete(), однако, если вы хотите очистить графическое окно сразу, проще воспользоваться функцией

clf(obj[, opt_job_arg])
// obj — дескриптор кадра или графического окна, или номер графического окна (если не указан, то применяется к текущему графическому
// окну),
// [, opt_job_arg] — флаг 'clear' (по умолчанию) или 'reset'
// clear — стирает объект со всеми потомками; для графика эффект аналогичен вызову delete(gca());
// reset — стирает потомков графического окна и возвращает все параметры по умолчанию.

Для получения дескрипторов различных графических объектов существует универсальная функция get(), а также несколько макросов на нее.

get()  возвращает дескриптор, либо значение параметра в зависимости от передаваемых аргументов
// Получение дескриптора
get(prop)
// prop — опция, которая может принимать следующие значения:
// 'current_entity' или 'hdl' (эквивалентный макрос gce())— возвращает дескриптор текущего или созданного последним графического объекта
// 'current_figure' (эквивалентный макрос gcf()) — возвращает дескриптор текущего потомка графического окна
// 'current_axes' (эквивалентный макрос gca()) — возвращает дескриптор текущих осей графика
// 'default_figure' (эквивалентный макрос gdf()) — возвращает стандартные настройки графического окна. Если их поменять, то
// все последующие окна будут наследовать именно эти настройки. Используется для создания пользовательских шаблонов
// 'default_axes' (эквивалентный макрос gda()) — возвращает стандартные настройки осей
// 'figures_id'  (эквивалентный макрос winsid) — возвращает вектор номеров открытых графических окон
// Получение значения параметра
get(h,prop)
// h — дескриптор
// prop — точное имя параметра того класса объектов, на который ссылается h
// данный вызов абсолютно аналогичен записи простого обращения к полю типизованного списка "h.prop"

Если вы помните номер графического окна, то получить его дескриптор можно с помощью функции

get_figure_handle(id_figure)
// id_figure — номер графического окна

Для установки значения параметра объекта вы, как мы это делали раньше, можете обратиться к параметру, как к полю типизованного списка, однако, есть еще специальная для этого функция set(). Преимущество функции перед простым обращением состоит в том, что вы можете использовать для получения дескрипторов макросы функции get() и не хранить дескрипторы в отдельных переменных.

set()  устанавливает значение для одного или нескольких параметров, выбранного объекта
set(h,prop,val[,prop2, val2, ..., propn, valn])
// h — дескриптор; рекомендуется его получать через макросы gce, gcf и gca;
// prop, prop2...propn — точное имя параметра объекта, на который ссылается дескриптор h
// val, val2...valn — значение, которое зависит от типа данных поля

Управление дескрипторами возможно через функции, реализующие следующие операции:

  • copy() — копирование. Позволяет полностью скопировать параметры объекта для записи их в другой дескриптор.
  • delete() — удаление. Позволяет удалить любой графический объект вместе с его потомками.
  • glue() — объединение. Позволяет объединить несколько графических объектов в один, на который будет ссылаться единственный дескриптор. Это бывает полезным при большом количестве потомков, когда форматирование их по отдельности занимает много времени — в этом случае их можно объединить в объект типа Compound.
  • unglue() — разъединение. Операция противоположная glue(). Работает с объектами типа Compound.
  • swap_handles() — помена местами. Позволяет поменять местами два объекта на одном уровне иерархии в дереве объектов графического окна.

Управлять графиками можно также с помощью мыши и инструментов графического окна. Все необходимые функции дублируются в раскрывающемся и контекстном меню. Например, чтобы очистить графическое окно, достаточно сделать активным, а затем в раскрывающемся меню Правка выбрать пункт Очистить графическое окно. Кроме того, вы также можете выделять построенные объекты и нажимая правой кнопкой мыши на них, вызывать контекстное меню, в котором доступны такие команды как Удалить, Копировать, Вставить и др. Все эти возможности на самом деле неявный вызов встроенных функций, позволяющие уменьшить количество рутинной работы. Однако, вам не стоит расслабляться по этому поводу, ведь без умения работать с этими функциями из командной строки или сценария, вы не сможете полноценно работать в среде.

Упражнение

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

-->scf();                     // создаем графическое окно
-->xsetech([0 0 1 0.5])       // создаем под-окно — выделяем верхнюю половину окна под график
-->-10:0.1:10;                // аргументы
-->plot2d(ans,ans.^2)         // строим график
-->xsetech([0 0.5 1 0.5])     // выделяем нижнюю половину окна под график
-->0:0.01:%pi;                // аргументы
-->polarplot(ans,sin(7*ans))  // строим график

Вы увидите два графика. Для построения, первым вызовом функции xsetech() мы передали позицию (в относительных единицах) на которой будет размещен верхний график. Первые два числа означают позицию верхнего левого угла подокна. Вторые два числа означают длину и высоту в относительных единицах, т.е. 1 означает, что подокно должно растянуться по всей длине, 0.5 — растягивание на половину высоты всего графического окна. Второй вызов xsetech() аналогичен первому, за исключением того, что верхний левый угол второго подокна должен занять позицию на половине высоты всего графического окна.

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

-->scf(1);                    // создаем графическое окно
-->f1=gca();                  // копируем дескриптор осей, автоматически созданных в окне 1
-->scf(0);                    // возвращаем активность окну 0
-->gcf;                       // получаем дескриптор окна 0
-->copy(ans.children(1),f1);  // копируем дескриптор в окно 1

Обратите внимание, что функции copy() мы первым аргументом передали источник, а вторым — место назначение. Сделав видимым окно 1, вы увидите, что график был скопирован с тем же форматированием и занимает ровно нижнюю половину окна, что не являлось первоначальной задумкой. Вообще говоря, функция скопировала разбивку окна 0 целиком, просто не скопировала наш график параболы. Давайте поправим внешний вид графика.

-->scf(1);                               // делаем окно 1 активным
-->f1=gcf();                             // копируем дескриптор окна 1 в переменную f1
-->delete(f1.children(2));               // удаляем пустые оси скопированные из окна 0
-->delete(f1.children(2));               // удаляем пустые оси, созданные для окна 1 автоматически
-->f1.children.axes_bounds = [0 0 1 1];  // исправляем масштабирование осей в графическом окне
                                         // вектор аналогичен вектору, с которым вызывалась xsetech()
-->scf(0); gcf; delete(ans.children(1)); // удаляем скопированный ранее график из окна 1

Теперь нарисуем в графическом окне 0 еще один график

-->-10:.01:10;
-->plot2d(ans,ans.^3)

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

-->f1=gcf();                                     // скопируем дескриптор графического окна 0
-->swap_handles(f1.children(1),f1.children(2))

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

Вы уже знаете, что за масштабирование осей отвечает параметр axes_bounds. Настроим график кубической параболы.

-->f1.children(1).axes_bounds=[0,0.5,1,0.5];

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

Наконец, продемонстрируем функцию glue(), название которой переводится как «клей», что намекает на ее назначение. Склеим оба графика.

-->glue([f1.children(1),f1.children(2)])     // обратите внимание, что дескрипторы передаются вектором
 ans  =
 
Handle of type "Compound" with properties:
==========================================
parent: Figure
children: ["Axes","Axes"]
visible = "on"
user_data = []
tag =

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

Построение графиков трехмерных функций[править]

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

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

Поверхности строятся следующими функциями:

  • plot3d() — строит поверхность по координатам;
  • plot3d1() — функция с расширенными возможностями настройки цвета;
  • plot3d2 — строит поверхность четырехсторонними полигонами;
  • plot3d3 — строит сетку четырехсторонними полигонами;
  • fplot3d() — строит поверхность по предопределенной функции;
  • surf() — строит поверхность.

Построение векторных графиков[править]

sin^2 x

Построение контурных графиков[править]

Построение градиентных графиков[править]

Построение гистограмм[править]

Настройка построенных графиков[править]

Сохранение графиков[править]