Задание значений отображаемых линий уровня




Рисование линий уровня

Чтобы построить линии уровня по данным, которые заданы в виде трех двумерных матриц (по данным, расположенным в узлах прямоугольной сетки), можно воспользоваться функциями countour или contourf из модуля pylab. Отличие этих двух функций состоит в том, что contourf, в отличие от contour, закрашивает области между линиями уровня однотонным цветом. Эти функции имеют некоторое количество параметров для настройки внешнего вида графика, но для начала ими можно пренебречь и передать в функцию только данные, по которым нужно построить линии уровня. Например:

# -*- coding: utf-8 -*-

import pylab
import numpy


def makeData():
x = numpy.arange(-10, 10, 0.05)
y = numpy.arange(-10, 10, 0.05)
xgrid, ygrid = numpy.meshgrid(x, y)

zgrid = (numpy.sin(xgrid * 0.3) * numpy.cos(ygrid * 0.75) /
(1 + numpy.abs(xgrid * ygrid) * 0.05))
return xgrid, ygrid, zgrid


if __name__ == '__main__':
x, y, z = makeData()
pylab.contour(x, y, z)

pylab.show()

Исходник

Результат будет выглядеть следующим образом:

Если заменить функцию contour на contourf, то результат будет следующий:

# -*- coding: utf-8 -*-

import pylab
import numpy


def makeData():
x = numpy.arange(-10, 10, 0.05)
y = numpy.arange(-10, 10, 0.05)
xgrid, ygrid = numpy.meshgrid(x, y)

zgrid = (numpy.sin(xgrid * 0.3) * numpy.cos(ygrid * 0.75) /
(1 + numpy.abs(xgrid * ygrid) * 0.05))
return xgrid, ygrid, zgrid


if __name__ == '__main__':
x, y, z = makeData()
pylab.contourf(x, y, z)

pylab.show()

Исходник

Добавление подписей к линиям уровня

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

Функции contour / contourf возвращают объект типа QuadContourSet (это производный класс от более общего класса ContourSet), который описывает наш график. Чтобы добавить на график подписи для линий уровня, нужно вызвать функцию clabel из модуля pylab. Эта Функция в качестве первого параметра ожидает экземпляр класса ContourSet. Таким образом, функции clabel в качестве первого параметра можно передать экземпляр класса, который был возвращен из функций contour / contourf.

# -*- coding: utf-8 -*-

import pylab
import numpy


def makeData():
x = numpy.arange(-10, 10, 0.05)
y = numpy.arange(-10, 10, 0.05)
xgrid, ygrid = numpy.meshgrid(x, y)

zgrid = (numpy.sin(xgrid * 0.3) * numpy.cos(ygrid * 0.75) /
(1 + numpy.abs(xgrid * ygrid) * 0.05))
return xgrid, ygrid, zgrid


if __name__ == '__main__':
x, y, z = makeData()
cs = pylab.contour(x, y, z)
pylab.clabel(cs)

pylab.show()

Исходник

Результат выглядит следующим образом:

Такого же результата можно добиться, если использовать не функцию clabel из pylab, а одноименный метод из класса QuadContourSet, то есть в предыдущем примере заменить строку pylab.clabel(cs) на cs.clabel().

Строго говоря, метод clabel класс QuadContourSet наследует от своего прародителя - класса ContourLabeler, а общая иерархия классов выглядит следующим образом:

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

Задание значений отображаемых линий уровня

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

В следующем примере мы задаем количество линий уровня, равное 20, а учитывая, что значения нашей функции лежит в интервале от -1 до 1, то расстояние между линиями уровня будет равно 0.1.

# -*- coding: utf-8 -*-

import pylab
import numpy


def makeData():
x = numpy.arange(-10, 10, 0.05)
y = numpy.arange(-10, 10, 0.05)
xgrid, ygrid = numpy.meshgrid(x, y)

zgrid = (numpy.sin(xgrid * 0.3) * numpy.cos(ygrid * 0.75) /
(1 + numpy.abs(xgrid * ygrid) * 0.05))
return xgrid, ygrid, zgrid


if __name__ == '__main__':
x, y, z = makeData()
cs = pylab.contour(x, y, z, 20)
pylab.clabel(cs)

pylab.show()

Исходник

Но мы можем явно задать интересующие нас уровни:

# -*- coding: utf-8 -*-

import pylab
import numpy


def makeData():
x = numpy.arange(-10, 10, 0.05)
y = numpy.arange(-10, 10, 0.05)
xgrid, ygrid = numpy.meshgrid(x, y)

zgrid = (numpy.sin(xgrid * 0.3) * numpy.cos(ygrid * 0.75) /
(1 + numpy.abs(xgrid * ygrid) * 0.05))
return xgrid, ygrid, zgrid


if __name__ == '__main__':
x, y, z = makeData()
levels = [-0.99, -0.7, -0.5, -0.3, -0.1, 0.0, 0.1, 0.3, 0.5, 0.7, 0.99]
cs = pylab.contour(x, y, z, levels)
pylab.clabel(cs)

pylab.show()

Исходник



Поделиться:




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

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-10-24 Нарушение авторских прав и Нарушение персональных данных


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