Главная страница

Книга Изучаем Python


Скачать 4.68 Mb.
НазваниеКнига Изучаем Python
Дата10.12.2022
Размер4.68 Mb.
Формат файлаpdf
Имя файлаErik_Metiz_Izuchaem_Python_Programmirovanie_igr_vizualizatsia_da.pdf
ТипКнига
#837531
страница36 из 53
1   ...   32   33   34   35   36   37   38   39   ...   53
Рис. 15.3. График с правильными данными
При вызове plot()
можно передавать многочисленные аргументы, а также ис- пользовать различные функции для настройки графиков. Знакомство с этими функциями продолжится позднее, когда мы начнем работать с более интересными наборами данных в этой главе.
Нанесение и оформление отдельных точек функцией scatter()
Иногда бывает полезно нанести на график отдельные точки, основанные на некото- рых характеристиках, и определить их оформление. Например, на графике малые и большие значения могут отображаться разными цветами. Возможны и другие варианты: например, сначала нанести множество точек с одним типом оформления, а затем выделить отдельные точки набора, перерисовав их с другим оформлением.
Для нанесения на диаграмму отдельной точки используется функция scatter()
Передайте scatter()
координаты (x, y) нужной точки, и функция нанесет эти значения на диаграмму:

Построение простого графика 315
scatter_squares.py
import matplotlib.pyplot as plt plt.scatter(2, 4)
plt.show()
Применим оформление, чтобы результат выглядел более интересно. Мы добавим название, метки осей, а также увеличим шрифт, чтобы текст нормально читался:
import matplotlib.pyplot as plt
 plt.scatter(2, 4, s=200)
# Назначение заголовка диаграммы и меток осей.
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# Назначение размера шрифта делений на осях.
plt.tick_params(axis='both', which='major', labelsize=14)
plt.show()
В точке  вызывается функция; аргумент s
задает размер точек, используемых для рисования диаграммы. Если запустить программу scatter_squares .py в текущем состоянии, вы увидите одну точку в середине диаграммы (рис. 15.4).
Рис. 15.4. Вывод одной точки
Вывод серии точек функцией scatter()
Чтобы вывести на диаграмме серию точек, передайте scatter()
списки значений координат x и y:

316 Глава 15 • Генерирование данных
scatter_squares.py
import matplotlib.pyplot as plt x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]
plt.scatter(x_values, y_values, s=100)
# Назначение заголовка диаграммы и меток осей.
Список x_values содержит числа, возводимые в квадрат, а в y_values содержатся квадраты. При передаче этих списков scatter()
библиотека matplotlib читает по одному значению из каждого списка и наносит их на диаграмму как точку.
Таким образом, на диаграмму будут нанесены точки (1, 1), (2, 4), (3, 9), (4, 16) и (5, 25); результат показан на рис. 15.5.
Рис. 15.5. Точечная диаграмма с несколькими точками
Автоматическое вычисление данных
Строить списки вручную неэффективно, особенно при большом объеме данных.
Вместо того чтобы передавать данные в виде списка, мы воспользуемся циклом
Python, который выполнит вычисления за нас. Вот как выглядит такой цикл для
1000 точек:
scatter_squares.py
import matplotlib.pyplot as plt
 x_values = list(range(1, 1001))
y_values = [x**2 for x in x_values]
 plt.scatter(x_values, y_values, s=40)

Построение простого графика 317
# Назначение заголовка диаграммы и меток осей.
# Назначение диапазона для каждой оси.
w plt.axis([0, 1100, 0, 1100000])
plt.show()
Все начинается со списка значений координаты x с числами от 1 до 1000 . Затем генератор списка строит значения
y
, перебирая значения
x
(
for x
in x_values
), воз- водя каждое число в квадрат (
x**2
) и сохраняя результаты в y_values
. Затем оба списка (входной и выходной) передаются scatter()
.
Набор данных достаточно велик, поэтому мы выбираем меньший размер шрифта, а функция axis()
используется для задания диапазона каждой оси . Функция axis()
получает четыре значения: минимум и максимум по осям x и y. В данном случае по оси x откладывается диапазон от 0 до 1100, а по оси y — диапазон от 0 до 1 100 000. На рис. 15.6 показан результат.
Рис. 15.6. Диаграмма с 1000 точками строится так же легко, как и диаграмма с 5 точками
Удаление контуров точек
Библиотека matplotlib позволяет раскрашивать точки на точечной диаграмме в разные цвета. Оформление по умолчанию — синие точки с черным контуром — хорошо подходит для диаграмм с несколькими точками. Однако при большом количестве точек черные контуры начинают сливаться. Чтобы удалить контуры вокруг точек, передайте аргумент edgecolor='none'
при вызове scatter()
:
plt.scatter(x_values, y_values, edgecolor='none', s=40)
Запустите scatter_squares .py с этим вызовом, и вы увидите, что на диаграмме выво- дятся только заполненные синие точки.

318 Глава 15 • Генерирование данных
Определение пользовательских цветов
Чтобы изменить цвет точек, передайте scatter()
аргумент c
с именем используе- мого цвета:
plt.scatter(x_values, y_values, c='red', edgecolor='none', s=40)
Также возможно определять пользовательские цвета в цветовой модели RGB. Что- бы определить цвет, передайте аргумент c
с кортежем из трех дробных значений
(для красной, зеленой и синей составляющих) в диапазоне от 0 до 1. Например, следующая строка создает диаграмму со светло-синими точками:
plt.scatter(x_values, y_values, c=(0, 0, 0.8), edgecolor='none', s=40)
Значения, близкие к 0, дают более темные цвета, а со значениями, близкими к 1, цвета получаются более светлыми.
Цветовые карты
Цветовая карта (colormap) представляет собой серию цветов градиента, опре- деляющую плавный переход от начального цвета к конечному. Цветовые карты используются в визуализациях для выделения закономерностей в данных. Напри- мер, малые значения можно обозначить светлыми цветами, а большие — темными.
Модуль pyplot включает набор встроенных цветовых карт. Чтобы воспользоваться одной из готовых карт, нужно указать, как модуль pyplot должен присваивать цвет каждой точке набора данных. В следующем примере цвет каждой точки присваи- вается на основании значения y:
scatter_squares.py
import matplotlib.pyplot as plt x_values = list(range(1001))
y_values = [x**2 for x in x_values]
plt.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues,
edgecolor='none', s=40)
# Назначение заголовка диаграммы и меток осей.
Мы передаем в c
список y-values
, а затем указываем pyplot
, какая цветовая карта должна использоваться, при помощи аргумента cmap
. Следующий код окрашивает точки с меньшими значениями y в светло-синий цвет, а точки с бульшими значениями y — в темно-синий цвет. Полученная диаграмма изо- бражена на рис. 15.7.
ПРИМЕЧАНИЕ
Все цветовые карты, доступные в pyplot, можно просмотреть на сайте http://matplotlib .org/; от- кройте раздел Examples, прокрутите содержимое до пункта Color Examples и щелкните на ссылке colormaps_reference .

Случайное блуждание 319
Рис. 15.7. Точечная диаграмма с цветовой картой Blues
Автоматическое сохранение диаграмм
Если вы хотите, чтобы программа автоматически сохраняла диаграмму в файле, замените вызов plt.show()
вызовом plt.savefig()
:
plt.savefig('squares_plot.png', bbox_inches='tight')
Первый аргумент содержит имя файла для сохранения диаграммы; файл будет со- хранен в одном каталоге с scatter_squares .py
. Второй аргумент отсекает от диаграм- мы лишние пропуски. Если вы хотите оставить пустые места вокруг диаграммы, этот аргумент можно опустить.
УПРАЖНЕНИЯ
15-1 . Кубы: число, возведенное в третью степень, называется «кубом» . Нанесите на диа- грамму первые пять кубов, а затем первые 5000 кубов .
15-2 . Цветные кубы: примените цветовую карту к диаграмме с кубами .
Случайное блуждание
В этом разделе мы используем Python для генерирования данных для случайного обхода, а затем при помощи matplotlib создадим привлекательное представление сгенерированных данных. Случайным блужданием (random walk) называется путь, который не имеет четкого направления, но определяется серией полностью случай- ных решений. Представьте, что муравей сошел с ума и делает каждый новый шаг в случайном направлении; его путь напоминает случайное блуждание.
Случайное блуждание находит практическое применение в естественных науках: физике, биологии, химии и экономике. Например, пыльцевое зерно на поверх- ности водяной капли движется по поверхности воды, потому что его постоянно подталкивают молекулы воды. Молекулярное движение в капле воды случайно,

320 Глава 15 • Генерирование данных поэтому путь пыльцевого зерна на поверхности представляет собой случайное блуждание. Код, который мы напишем, найдет применение при моделировании многих реальных ситуаций.
Создание класса RandomWalk()
Чтобы создать путь случайного блуждания, мы создадим класс
RandomWalk
, кото- рый принимает случайные решения по выбору направления. Классу нужны три атрибута: переменная для хранения количества точек в пути и два списка для координат x и y каждой точки.
Класс
RandomWalk содержит всего два метода:
__init__()
и fill_walk()
для вычис- ления точек случайного блуждания. Начнем с метода
__init__()
:
random_walk.py
 from random import choice class RandomWalk():
"""Класс для генерирования случайных блужданий."""
 def __init__(self, num_points=5000):
"""Инициализирует атрибуты блуждания."""
self.num_points = num_points
# Все блуждания начинаются с точки (0, 0).
 self.x_values = [0]
self.y_values = [0]
Чтобы принимать случайные решения, мы сохраним возможные варианты в списке и используем функцию choice()
для принятия решения . Затем для списка уста- навливается количество точек по умолчанию равным 5000 — достаточно большим, чтобы генерировать интересные закономерности, но достаточно малым, чтобы блуждания генерировались быстро . Затем в точке  создаются два списка для хранения значений x и y, после чего каждый путь начинается с точки (0, 0).
Выбор направления
Метод fill_walk()
, как показано ниже, заполняет путь точками и определяет на- правление каждого шага. Добавьте этот метод в random_walk .py
:
random_walk.py
def fill_walk(self):
"""Вычисляет все точки блуждания."""
# Шаги генерируются до достижения нужной длины.
 while len(self.x_values) < self.num_points:
# Определение направления и длины перемещения.
 x_direction = choice([1, -1])
x_distance = choice([0, 1, 2, 3, 4])
 x_step = x_direction * x_distance

Случайное блуждание 321
y_direction = choice([1, -1])
y_distance = choice([0, 1, 2, 3, 4])
 y_step = y_direction * y_distance
# Отклонение нулевых перемещений.
 if x_step == 0 and y_step == 0:
continue
# Вычисление следующих значений x и y.
 next_x = self.x_values[-1] + x_step next_y = self.y_values[-1] + y_step self.x_values.append(next_x)
self.y_values.append(next_y)
В точке  запускается цикл, который выполняется вплоть до заполнения пути правильным количеством точек. Главная часть этого метода сообщает Python, как следует моделировать четыре случайных решения: двигаться ли вправо или влево?
Как далеко идти в этом направлении? Двигаться ли вверх или вниз? Как далеко идти в этом направлении?
Выражение choice([1,
-1])
выбирает значение x_direction
; оно возвращает 1 для перемещения вправо или –1 для движения влево . Затем выражение choice([0,
1,
2,
3,
4])
определяет дальность перемещения в этом направлении (
x_distance
) случайным выбором целого числа от 0 до 4. (Включение 0 позволяет выполнять шаги по оси y
, а также шаги со смещением по обеим осям.)
В точках  и  определяется длина каждого шага в направлениях x
и y
, для чего направление движения умножается на выбранное расстояние. При положительном результате x_step смещает вправо, при отрицательном — влево, при нулевом — вертикально. При положительном результате y_step смещает вверх, при отрица- тельном — вниз, при нулевом — горизонтально. Если оба значения x_step и y_step равны 0, то блуждание останавливается, но цикл продолжается .
Чтобы получить следующее значение x
, мы прибавляем значение x_step к по- следнему значению, хранящемуся в x_values

, и делаем то же самое для значе- ний y
. После того как значения будут получены, они присоединяются к x_values и y_values
Вывод случайного блуждания
Ниже приведен код отображения всех точек блуждания:
rw_visual.py
import matplotlib.pyplot as plt from random_walk import RandomWalk
# Построение случайного блуждания и нанесение точек на диаграмму.
 rw = RandomWalk()
rw.fill_walk()
 plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()

322 Глава 15 • Генерирование данных
Сначала программа импортирует pyplot и
RandomWalk
. Затем она создает случайное блуждание и сохраняет его в rw
, не забывая вызвать fill_walk()
. В точке  про- грамма передает scatter()
координаты x
и y
блуждания и выбирает подходящий размер точки.
На рис. 15.8 показана диаграмма с 5000 точками. (В изображениях этого раз- дела область просмотра matplotlib не показана, но вы увидите ее при запуске rw_visual .py
.)
Рис. 15.8. Случайное блуждание с 5000 точек
Генерирование нескольких случайных блужданий
Все случайные блуждания отличаются друг от друга; интересно понаблюдать за тем, какие узоры генерирует программа. Один из способов использования предыдущего кода — построить несколько блужданий без многократного запуска программы в цикле while
:
rw_visual.py
import matplotlib.pyplot as plt from random_walk import RandomWalk
# Новые блуждания строятся до тех пор, пока программа остается активной.
while True:
# Построение случайного блуждания и нанесение точек на диаграмму.
rw = RandomWalk()
rw.fill_walk()
plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()
 keep_running = input("Make another walk? (y/n): ")
if keep_running == 'n':
break

Случайное блуждание 323
Код генерирует случайное блуждание, отображает его в области просмотра matplotlib и делает паузу с открытой областью просмотра. Когда вы закрываете область просмотра, программа спрашивает, хотите ли вы сгенерировать следующее блуждание. Ответьте y
, и вы сможете сгенерировать блуждания, которые начина- ются рядом с начальной точкой, а затем отклоняются преимущественно в одном направлении; при этом большие группы будут соединяться тонкими секциями.
Чтобы завершить программу, введите n
ПРИМЕЧАНИЕ
Если у вас версия Python 2 .7, используйте raw_input() вместо input() в точке  .
Оформление случайного блуждания
В этом разделе мы настроим диаграмму так, чтобы подчеркнуть важные ха- рактеристики каждого блуждания и отвести на второй план несущественные элементы. Для этого мы выделим характеристики, которые нужно подчеркнуть
(например, откуда началось блуждание, где оно закончилось и по какому пути следовало). Затем определяются характеристики, которые нужно ослабить (на- пример, деления шкалы и метки). Результатом должно быть простое визуальное представление, которое четко описывает путь, использованный в каждом слу- чайном блуждании.
Назначение цветов
Мы используем цветовую карту для отображения точек блуждания, а также уда- ляем черный контур из каждой точки, чтобы цвет точек был лучше виден. Чтобы точки окрашивались в соответствии с их позицией в блуждании, мы передаем в ар- гументе c
список с позицией каждой точки. Так как точки выводятся по порядку, список просто содержит числа от 1 до 5000:
rw_visual.py
while True:
# Построение случайного блуждания и нанесение точек на диаграмму.
rw = RandomWalk()
rw.fill_walk()
 point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
edgecolor='none', s=15)
plt.show()
keep_running = input("Make another walk? (y/n): ")
В точке  функция range()
используется для генерирования списка чисел, размер которого равен количеству точек в блуждании. Полученный результат сохраняется в списке point_numbers
, который используется для назначения цвета каждой точки

324 Глава 15 • Генерирование данных в блуждании. Мы передаем point_numbers в аргументе c
, используем цветовую карту
Blues и затем передаем edgecolor=none для удаления черного контура вокруг каждой точки. В результате создается диаграмма блуждания с градиентным пере- ходом от светло-синего к темно-синему (рис. 15.9).
Рис. 15.9. Случайное блуждание, окрашенное с применением цветовой карты Blues
Начальные и конечные точки
Помимо раскраски точек, обозначающей их позицию, было бы неплохо видеть, где начинается и заканчивается каждое блуждание. Для этого можно прорисовать пер- вую и последнюю точки отдельно, после нанесения на диаграмму основной серии.
Мы выведем конечные точки с большим размером и с другим цветом, чтобы они выделялись на общем фоне:
rw_visual.py
while True:
plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
edgecolor='none', s=15)
# Выделение первой и последней точек.
plt.scatter(0, 0, c='green', edgecolors='none', s=100)
plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none',
s=100)
plt.show()

Случайное блуждание 325
Чтобы вывести начальную точку, мы рисуем точку (0, 0) зеленым цветом с боль- шим размером (
s
=100) по сравнению с остальными точками. Для выделения конеч- ной точки последняя пара координат x и y выводится с размером 100. Обязательно вставьте этот код непосредственно перед вызовом plt.show()
, чтобы начальная и конечная точки выводились поверх всех остальных точек.
При выполнении этого кода вы будете точно видеть, где начинается и кончается каждое блуждание. (Если конечные точки не выделяются достаточно четко, на- страивайте их цвет и размер, пока не достигнете желаемого результата.)
Удаление осей
Уберем оси с диаграммы, чтобы они не отвлекали зрителя от общей картины.
Для удаления осей используется следующий код:
rw_visual.py
while True:
plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none',
s=100)
# Удаление осей.
 plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
Функция plt.axes()
 переводит флаг видимости каждой оси в состояние
False
При работе с визуализацией подобные цепочки вызовов встречаются очень часто.
Запустите программу rw_visual .py
; теперь выводимые диаграммы не имеют осей.
Добавление точек
Увеличим количество точек, чтобы работать с большим объемом данных. Для этого мы увеличим значение num_points при создании экземпляра
RandomWalk и отрегу- лируем размер каждой точки при выводе диаграммы:
rw_visual.py
while True:
# Построение случайного блуждания и нанесение точек на диаграмму.
rw = RandomWalk(50000)
rw.fill_walk()
# Вывод точек и отображение диаграммы.
point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
edgecolor='none', s=1)

1   ...   32   33   34   35   36   37   38   39   ...   53


написать администратору сайта