Как очистить график в питоне
Перейти к содержимому

Как очистить график в питоне

  • автор:

Как удалить график matplotlib в PyQt5

Author24 — интернет-сервис помощи студентам

Есть следующее задание: Задача 1. В созданном окне вам необходимо построить график функций на осях x и y по заданной формуле: (формула).
Задача 2. Используйте предыдущее окно с нарисованным графиком, вам необходимо:
1. Создать цветное текстовое сообщение “Радуга”.
. . . и так далее.

С помощью следующего кода вывожу график:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
# -*- coding: utf-8 -*- import sys import matplotlib.pyplot as plt from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure import numpy as np from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(887, 720) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName("horizontalLayout") self.frame = QtWidgets.QFrame(self.centralwidget) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.verticalLayout = QtWidgets.QVBoxLayout(self.frame) self.verticalLayout.setObjectName("verticalLayout") self.frame_2 = QtWidgets.QFrame(self.frame) self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_2.setObjectName("frame_2") self.verticalLayout.addWidget(self.frame_2) self.frame_3 = QtWidgets.QFrame(self.frame) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth()) self.frame_3.setSizePolicy(sizePolicy) self.frame_3.setFocusPolicy(QtCore.Qt.NoFocus) self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_3.setObjectName("frame_3") self.verticalLayout.addWidget(self.frame_3) self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.frame_3) self.horizontalLayout_3.setObjectName("horizontalLayout_3") ##Canvas Here self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) ##end of Canvas ##Add Canvas self.horizontalLayout_3.addWidget(self.canvas) ##end of horizontal layout self.frame_4 = QtWidgets.QFrame(self.frame) self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_4.setObjectName("frame_4") self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_4) self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_2.setSpacing(0) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.pushButton = QtWidgets.QPushButton(self.frame_4, clicked=lambda: self.clearCanvas()) self.pushButton.setStyleSheet("QPushButton\n" " background-color: rgb(0, 200,96);\n" " border: none;\n" " padding: 5px;\n" " color: rgb(205, 230, 255);\n" " border-radius: 5px;\n" " font: 75 14pt \"Candara\";\n" ">\n" "\n" "QPushButton:hover\n" " background-color: rgb(0, 240, 115);\n" ">\n" "QPushButton:pressed\n" " background-color: rgb(0, 200, 96);\n" ">") self.pushButton.setObjectName("pushButton") self.horizontalLayout_2.addWidget(self.pushButton) self.verticalLayout.addWidget(self.frame_4, 0, QtCore.Qt.AlignBottom) self.horizontalLayout.addWidget(self.frame) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 887, 26)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) self.drawPlot() #Здесь рисуется график QtCore.QMetaObject.connectSlotsByName(MainWindow def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "Do Next")) def drawPlot(self): self.figure.clear() plt.title("Graph") plt.xlabel("X-label") plt.ylabel("Y-label") x = np.linspace(0, 10, 100) y = (1 - 10 * x - ((x * x) / 13)) * np.tan(x * x * x) plt.plot(x, y) self.canvas.draw() def clearCanvas(self): self.horizontalLayout_3.removeWidget(self.canvas) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())

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

self.figure.clear()

Как мне удалить график matplotlib, чтобы потом встал на его место новый график?

Написал программу , но не знаю что именно нужно удалить в QWidget , чтобы туда вставился новый график matplotlib
Удалял разные части и получал разные ошибки, но в основном это была она «QLayout: Attempting to add QLayout «» to QWidget «widget», which already has a layout»

# -*- coding: utf-8 -*- from PySide2 import QtCore, QtGui, QtWidgets import sys from PySide2.QtCore import * from PySide2.QtGui import * from PySide2.QtWidgets import * from ui_Postroeni9 import Ui_MainWindow from graf0 import graf0stroy from graf0canvas import MyMplCanvas from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self.lineEdit_2.setText("0") self.lineEdit_3.setText("0") self.lineEdit.setText("0") self.lineEdit_4.setText("0") self.lineEdit_5.setText("0") self.lineEdit_6.setText("0") self.lineEdit_7.setText("0") self.pushButton.clicked.connect(self.stroygraf01) self.pushButton_4.clicked.connect(self.stroygraf01) self.pushButton_5.clicked.connect(self.stroygraf01) self.pushButton_7.clicked.connect(self.stroygraf01) self.pushButton_2.clicked.connect(self.update_plot) def stroygraf01(self): self.fig0 = graf0stroy(self, kindex=float(self.lineEdit_2.text()), bindex=float(self.lineEdit_3.text())) self.companovka_for_mpl = QtWidgets.QVBoxLayout(self.widget) self.canavas = MyMplCanvas(self.fig0) self.companovka_for_mpl.addWidget(self.canavas) self.toolBar = NavigationToolbar(self.canavas, self) self.companovka_for_mpl.addWidget(self.toolBar) def update_plot(self): self.companovka_for_mpl.deleteLater() if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) w = MainWindow() w.show() sys.exit(app.exec_())

это основной файл где всё происходит , удаляю график функцией update_plot
Как мне удалить график, чтобы при выполнении функции stroygraf01 у меня построился новый?
честно я не понимаю немного , т.к. зеленый
Уповаю на вашу помощь

  • Вопрос задан более года назад
  • 102 просмотра

Как можно стереть (удалить) лишние графики в matplotlib

После нахождения точки пересечения двух прямых требуется оставить только оси координат и полученную точку. Мой код:

import numpy as np import matplotlib.pyplot as plt #fig = plt.figure() #ls = fig.add_subplot(111) fig, ls = plt.subplots() p,q,v,k,b1=2,4,3,4,6 X = np.arange(-50, 50, 0.05) Y = k*X plt.plot(X,Y) ls.plot(q,0) ls.scatter(q, 0, color='orange', marker='o') ls.text(q, 0.3, "Q", horizontalalignment="center") ls.plot(p,0) ls.scatter(p, 0, color='orange', marker='o') ls.text(p, 0.3, "P", horizontalalignment="center") ls.plot(-v,0) ls.scatter(-v, 0, color='orange', marker='o') ls.text(-v, 0.8, "V", horizontalalignment="center") xmin,xmax,ymin,ymax=-10,10,-10,10 ax = plt.gca() ax.get_xlim() ax.set_xlim([xmin,xmax]) ax.set_ylim([ymin,ymax]) ax.spines['left'].set_position('center') ax.spines['bottom'].set_position('center') ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) x, y = np.meshgrid(X, X) ls.plot(0.0,b1) ls.scatter(0.0, b1, color='blue', marker='o') ls.text(0.8, b1, "B1", horizontalalignment="center") l1 = b1*x+b1*v - v*y vb = ls.contour(x,y, l1, [0], colors='red') l2 = -b1*X/p + b1 ls.plot(X,l2) idx = np.argwhere(np.diff(np.sign(Y - l2))).flatten() plt.plot(X[idx], Y[idx], 'ro') plt.text(X[idx]+0.1, Y[idx], "S", horizontalalignment="center") # ls.cla() plt.show() 

Результат работы программы

Пользуясь вопросом https://stackoverflow.com/questions/8213522/when-to-use-cla-clf-or-close-for-clearing-a-plot-in-matplotlib пробовал реализовать различные способы:

plt.close(ls) fig.clf() plt.close(fig) ls.cla() 

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

Визуализация данных с matplotlib

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

Модуль matplotlib.pyplot предоставляет процедурный интерфейс к (объектно-ориентированной) библиотеке matplotlib, который во многом копирует инструменты пакета MATLAB. Инструменты модуля pyplot де-факто являются стандартным способом работы с библиотекой matplotlib , поэтому мы органичимся рассмотрением этого пакета.

Двумерные графики

pyplot.plot

Нарисовать графики функций sin и cos с matplotlib.pyplot можно следующим образом:

import numpy as np import matplotlib.pyplot as plt phi = np.linspace(0, 2.*np.pi, 100) plt.plot(phi, np.sin(phi)) plt.plot(phi, np.cos(phi)) plt.show() 

В результате получаем

ex1

Мы использовали функцию plot, которой передали два параметра — списки значений по горизонтальной и вертикальной осям. При последовательных вызовах функции plot графики строятся в одних осях, при этом происходит автоматическое переключение цвета.

fmt = '[marker][line][color]' 

функции plot позволяет задавать тип маркера, тип линии и цвет. Приведем несколько примеров:

x = np.linspace(0, 1, 100) f1 = 0.25 - (x - 0.5)**2 f2 = x**3 plt.plot(x, f1, ':b') # пунктирная синяя линия plt.plot(x, f2, '--r') # штрихованная красная линия plt.plot(x, f1+f2, 'k') # черная непрерывная линия plt.show() 

ex2

rg = np.random.Generator(np.random.PCG64()) plt.plot(rg.binomial(10, 0.3, 6), 'ob') # синие круги plt.plot(rg.poisson(7, 6), 'vr') # красные треугольники plt.plot(rg.integers(0, 10, 6), 'Dk') # черные ромбы plt.show() 

ex3

Из последнего примера видно, что если в функцию plot передать только один список y , то он будет использован для значений по вертикальной оси. В качестве значений по горизонтальной оси будет использован range(len(y)) .

Более тонкую настройку параметров можно выполнить, передавая различные именованные аргументы, например:

  • marker : str — тип маркера
  • markersize : float — размер маркера
  • linestyle : str — тип линии
  • linewidth : float — толщина линии
  • color : str — цвет

Полный список доступных параметров можно найти в документации.

pyplot.errorbar

Результаты измерений в физике чаще всего представлены в виде величин с ошибками. Функция plt.errorbar позволяет отображать такие данные:

rg = np.random.Generator(np.random.PCG64(5)) x = np.arange(6) y = rg.poisson(149, x.size) plt.errorbar(x, y, yerr=np.sqrt(y), marker='o', linestyle='none') plt.show() 

ex4

Ошибки можно задавать и для значений по горизонтальной оси:

rg = np.random.Generator(np.random.PCG64(5)) N = 6 x = rg.poisson(169, N) y = rg.poisson(149, N) plt.errorbar(x, y, xerr=np.sqrt(x), yerr=np.sqrt(y), marker='o', linestyle='none') plt.show() 

ex5

Ошибки измерений могут быть асимметричными. Для их отображения в качестве параметра yerr (или xerr ) необходимо передать кортеж из двух списков:

rg = np.random.Generator(np.random.PCG64(11)) N = 6 x = np.arange(N) y = rg.poisson(149, N) yerr = [ 0.7*np.sqrt(y), 1.2*np.sqrt(y) ] plt.errorbar(x, y, yerr=yerr, marker='o', linestyle='none') plt.show() 

ex6

Функция pyplot.errorbar поддерживает настройку отображения графика с помощью параметра fmt и всех именованных параметров, которые доступны в функции pyplot . Кроме того, здесь появляются параметры для настройки отображения линий ошибок (“усов”):

  • ecolor : str — цвет линий ошибок
  • elinewidth : float — ширина линий ошибок
  • capsize : float — длина “колпачков” на концах линий ошибок
  • capthick : float — толщина “колпачков” на концах линий ошибок

и некоторые другие. Изменим параметры отрисовки данных из предыдущего примера:

# . plt.errorbar(x, y, yerr=yerr, marker='o', linestyle='none', ecolor='k', elinewidth=0.8, capsize=4, capthick=1) plt.show() 

ex7

Настройки отображения

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

Диапазон значений осей

Задавать диапазон значений осей в matplotlib можно несколькими способами. Например, так:

pyplot.xlim([0, 200]) # диапазон горизонтальной оси от 0 до 200 pyplot.xlim([0, 1]) # диапазон вертикальной оси от 0 до 1 

Размер шрифта

Размер и другие свойства шрифта, который используется в matplotlib по умолчанию, можно изменить с помощью объекта matplotlib.rcParams :

matplotlib.rcParams.update('font.size': 14>) 

Объект matplotlib.rcParams хранит множество настроек, изменяя которые, можно управлять поведением по умолчанию. Смотрите подробнее в документации.

Подписи осей

Подписи к осям задаются следующим образом:

plt.xlabel('run number', fontsize=16) plt.ylabel(r'average current ($\mu A$)', fontsize=16) 

В подписях к осям (и вообще в любом тексте в matplotlib) можно использовать инструменты текстовой разметки TeX, позволяющие отрисовывать различные математические выражения. TeX-выражения должны быть внутри пары символов $ , кроме того, их следует помещать в r-строки, чтобы избежать неправильной обработки.

Заголовок

Функция pyplot.title задает заголовок диаграммы. Применим наши новые знания:

import numpy as np import matplotlib.pyplot as plt import matplotlib # задаем размер шрифта matplotlib.rcParams.update('font.size': 12>) rg = np.random.Generator(np.random.PCG64(11)) x = np.arange(6) y = rg.poisson(149, x.size) yerr = [ 0.7*np.sqrt(y), 1.2*np.sqrt(y) ] plt.errorbar(x, y, yerr=yerr, marker='o', linestyle='none', ecolor='k', elinewidth=0.8, capsize=4, capthick=1) # добавляем подписи к осям и заголовок диаграммы plt.xlabel('run number', fontsize=16) plt.ylabel(r'average current ($\mu A$)', fontsize=16) plt.title(r'The $\alpha^\prime$ experiment. Season 2020-2021') # задаем диапазон значений оси y plt.ylim([0, 200]) # оптимизируем поля и расположение объектов plt.tight_layout() plt.show() 

ex8

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

Легенда

При построении нескольких графиков в одних осях полезно добавлять легенду — пояснения к каждой линии. Следующий пример показывает, как это делается с помощью аргументов label и функции pyplot.legend :

import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams.update('font.size': 12>) x = np.linspace(0, 1, 100) f1 = 0.25 - (x - 0.5)**2 f2 = x**3 # указываем в аргументе label содержание легенды plt.plot(x, f1, ':b', label='1st component') plt.plot(x, f2, '--r', label='2nd component') plt.plot(x, f1+f2, 'k', label='total') plt.xlabel(r'$x$', fontsize=16) plt.ylabel(r'$f(x)$', fontsize=16) plt.xlim([0, 1]) plt.ylim([0, 1]) # выводим легенду plt.legend(fontsize=14) plt.tight_layout() plt.show() 

ex9

Функция pyplot.legend старается расположить легенду так, чтобы она не пересекала графики. Аргумент loc позволяет задать расположение легенды вручную. В большинстве случаев расположение по умолчанию получается удачным. Детали и описание других аргументов смотрите в документации.

Сетка

Сетка во многих случаях облегчает анализ графиков. Включить отображение сетки можно с помощью функции pyplot.grid . Аргумент axis этой функции имеет три возможных значения: x , y и both и определяет оси, вдоль которых будут проведены линии сетки. Управлять свойствами линии сетки можно с помощью именованных аргументов, которые мы рассматривали выше при обсуждении функции pyplot.plot .

В matplotlib поддерживается два типа сеток: основная и дополнительная. Выбор типа сетки выполняется с помощью аргумента which , который может принимать три значения: major , minor и both . По умолчанию используется основная сетка.

Линии сетки привязаны к отметкам на осях. Чтобы работать с дополнительной сеткой необходимо сначала включить вспомогательные отметки на осях (которые по умолчанию отключены и к которым привязаны линии дополнительной сетки) с помощью функции pyplot.minorticks_on . Приведем пример:

import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams.update('font.size': 12>) x = np.linspace(-1, 1, 250) plt.plot(x, x, label=r'$x$') plt.plot(x, x**2, label=r'$x^2$') plt.plot(x, x**3, label=r'$x^3$') plt.plot(x, np.cbrt(x), label=r'$x^$') plt.legend(fontsize=16) # включаем дополнительные отметки на осях plt.minorticks_on() plt.xlabel(r'$x$', fontsize=16) plt.xlim([-1., 1.]) plt.ylim([-1., 1.]) # включаем основную сетку plt.grid(which='major') # включаем дополнительную сетку plt.grid(which='minor', linestyle=':') plt.tight_layout() plt.show() 

ex10

Логарифмический масштаб

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

ex11

plt.semilogy() 

делает график гораздо более информативным:

ex12

Теперь мы видим поведение функций во всем динамическом диапазоне, занимающем 12 порядков.

Произвольные отметки на осях

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

ex13

Метки на горизонтальной оси были заданы с помощью функции pyplot.xticks :

plt.xticks( np.linspace(-np.pi, np.pi, 9), [r'$-\pi$', r'$-3\pi/4$', r'$-\pi/2$', r'$-\pi/4$', r'$0$', r'$\pi/4$', r'$+\pi/2$', r'$3\pi/4$', r'$+\pi$']) 

Модуль pyplot.ticker содержит более продвинутые инструменты для управления отметками на осях. Подробности смотрите в документации.

Размер изображения

До сих пор мы строили графики в одном окне, размер которого был задан по умолчанию. За кадром matplotlib создавал объект типа Figure, который определяет размер окна и содержит все остальные элементы. Кроме того, автоматически создавался объект типа Axis. Подробнее работа с этими объектами будет рассмотрена ниже. Сейчас же мы рассмотрим функцию pyplot.figure , которая позволяет создавать новые объекты типа Figure и переключаться между уже созданными объектами.

Функция pyplot.figure может принимать множество аргументов. Вот основные:

  • num : int или str — уникальный идентификатор объекта типа. Если задан новый идентификатор, то создается новый объект и он становится активным. В случае, если передан идентификатор уже существующего объекта, то этот объект возвращается и становится активным
  • figsize : (float, float) — размер изображения в дюймах
  • dpi : float — разрешение в количестве точек на дюйм

Описание других параметров функции pyplot.figure можно найти в документации. Используем эту функцию и функцию pyplot.axis чтобы улучшить наш пример с построением степенных функций:

ex14

Мы добавили две строки по сравнению с прошлой версией:

fig = plt.figure(figsize=(6, 6)) # . plt.axis('equal') 

Функция pyplot.axis позволяет задавать некоторые свойства осей. Ее вызов с параметром ‘equal’ делает одинаковыми масштабы вертикальной и горизонтальной осей, что кажется хорошей идеей в этом примере. Функция pyplot.axis возвращает кортеж из четырех значений xmin, xmax, ymin, ymax , соответствующих границам диапазонов значений осей.

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

  • Кортеж из четырех float задаст новые границы диапазонов значений осей
  • Строка ‘off’ выключит отображение линий и меток осей

Гистограммы

Обратимся теперь к другим типам диаграмм. Функция pyplot.hist строит гистограмму по набору значений:

import numpy as np import matplotlib.pyplot as plt rg = np.random.Generator(np.random.PCG64(5)) data = rg.poisson(145, 10000) plt.hist(data, bins=40) # для краткости мы опускаем код для настройки осей, сетки и т.д. 

ex15

Аргумент bins задает количество бинов гистограммы. По умолчанию используется значение 10. Если вместо целого числа в аргумент bins передать кортеж значений, то они будут использованы для задания границ бинов. Таким образом можно построить гистограмму с произвольным разбиением.

Некоторые другие аргументы функции pyplot.hist :

  • range : (float, float) — диапазон значений, в котором строится гистограмма. Значения за пределами заданного диапазона игнорируются.
  • density : bool . При значении True будет построена гистограмма, соответствующая плотности вероятности, так что площадь гистограммы будет равна единице.
  • weights : список float значений того же размера, что и набор данных. Определяет вес каждого значения при построении гистограммы.
  • histtype : str . может принимать значения . Определяет тип отрисовки гистограммы.

В качестве первого аргумента можно передать кортеж наборов значений. Для каждого из них будет построена гистограмма. Аргумент stacked со значением True позволяет строить сумму гистограмм для кортежа наборов. Покажем несколько примеров:

ex18

rg = np.random.Generator(np.random.PCG64(5)) data1 = rg.poisson(145, 10000) data2 = rg.poisson(140, 2000) # левая гистограмма plt.hist([data1, data2], bins=40) # центральная гистограмма plt.hist([data1, data2], bins=40, histtype='step') # правая гистограмма plt.hist([data1, data2], bins=40, stacked=True) 

В физике гистограммы часто представляют в виде набора значений с ошибками, предполагая при этом, что количество событий в каждом бине является случайной величиной, подчиняющейся биномиальному распределению. В пределе больших значений флуктуации количества событий в бине могут быть описаны распределением Пуассона, так что характерная величина флуктуации определяется корнем из числа событий. Библиотека matplotlib не имеет инструмента для такого представления данных, однако его легко получить с помощью комбинации numpy.histogram и pyplot.errorbar :

def poisson_hist(data, bins=60, lims=None): """ Гистограмма в виде набора значений с ошибками """ hist, bins = np.histogram(data, bins=bins, range=lims) bins = 0.5 * (bins[1:] + bins[:-1]) return (bins, hist, np.sqrt(hist)) rg = np.random.Generator(np.random.PCG64(5)) data = rg.poisson(145, 10000) x, y, yerr = poisson_hist(data, bins=40, lims=(100, 190)) plt.errorbar(x, y, yerr=yerr, marker='o', markersize=4, linestyle='none', ecolor='k', elinewidth=0.8, capsize=3, capthick=1) 

ex19

Диаграммы рассеяния

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

rg = np.random.Generator(np.random.PCG64(5)) means = (0.5, 0.9) covar = [ [1., 0.6], [0.6, 1.] ] data = rg.multivariate_normal(means, covar, 5000) plt.scatter(data[:,0], data[:,1], marker='o', s=1) 

ex20

Каждой паре значений в наборе данных соответствует одна точка на диаграмме. Несмотря на свою простоту, диаграмма рассеяния позволяет во многих случаях наглядно представлять двумерные данные. Функция pyplot.scatter позволяет визуализировать и данные более высокой размерности: размер и цвет маркера могут быть заданы для каждой точки отдельно:

rg = np.random.Generator(np.random.PCG64(4)) data = rg.uniform(-1, 1, (50, 2)) col = np.arctan2(data[:, 1], data[:, 0]) size = 100*np.sum(data**2, axis=1) plt.scatter(data[:,0], data[:,1], marker='o', s=size, c=col) 

ex21

Цветовую палитру можно задать с помощью аргумента cmap . Подробности и описание других аргументов функции pyplot.scatter можно найти в документации.

Контурные диаграммы

Контурные диаграммы позволяют визуализировать функции двух переменных:

from scipy import stats means = (0.5, 0.9) covar = [ [1., 0.6], [0.6, 1.] ] mvn = stats.multivariate_normal(means, covar) x, y = np.meshgrid( np.linspace(-3, 3, 80), np.linspace(-2, 4, 80) ) data = np.dstack((x, y)) # левая диаграмма — без заливки цветом plt.contour(x, y, mvn.pdf(data), levels=10) # правая диаграмма — с заливкой цветом plt.contourf(x, y, mvn.pdf(data), levels=10) 

ex22

Аргумент levels задает количество контуров. По умолчанию контуры отрисовываются равномерно между максимальным и минимальным значениями. В аргумент levels также можно передать список уровней, на которых следует провести контуры.

Обратите внимание на использование функций numpy.meshgrid и numpy.dstack в этом примере.

Контурную диаграмму можно дополнить цветовой полосой colorbar , вызвав функцию pyplot.colorbar :

cs = plt.contourf(x, y, mvn.pdf(data), levels=15, cmap=matplotlib.cm.magma_r) cbar = plt.colorbar(cs) 

ex23

Более подробное описание функций plt.contour и plt.contourf смотрите в документации.

Расположение нескольких осей в одном окне

В одном окне (объекте Figure ) можно разместить несколько осей (объектов axis.Axis ). Функция pyplot.subplots создает объект Figure , содержащий регулярную сетку объектов axis.Axis :

import numpy as np from scipy import stats import matplotlib.pyplot as plt fig, axes = plt.subplots(ncols=3, nrows=2, figsize=(12, 8)) x = np.linspace(0.01, 25, 250) for idx, row in enumerate(axes): for jdx, ax in enumerate(row): ndf = idx * 3 + jdx + 1 y = stats.chi2.pdf(x, ndf) ax.plot(x, y, label=fr'$\chi^2_ndf>>>(x)$') ax.set_xlabel(r'$x$', fontsize=16) ax.set_ylim([0, 1.05*y.max()]) ax.minorticks_on() ax.legend(fontsize=16) ax.grid(which='major') ax.grid(which='minor', linestyle=':') fig.tight_layout() plt.show() 

ex24

Количество строк и столбцов, по которым располагаются различные оси, задаются с помощью параметров nrows и ncols , соответственно. Функция pyplot.subplots возвращает объект Figure и двумерный список осей axis.Axis . Обратите внимание на то, что вместо вызовов функций модуля pyplot в этом примере использовались вызовы методов классов Figure и axis.Axis .

В последнем примере горизонтальная ось во всех графиках имеет один и тот же диапазон. Аргумент sharex функции pyplot.subplots позволяет убрать дублирование отрисовки осей в таких случаях:

fig, axes = plt.subplots(ncols=3, nrows=2, figsize=(12, 8), sharex=True) # . for idx, row in enumerate(axes): for jdx, ax in enumerate(row): # . if idx: ax.set_xlabel(r'$x$', fontsize=16) 

ex25

Существует аналогичный параметр sharey для вертикальной оси.

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

Функция pyplot.axes позволяет добавлять новые оси в текущем окне в произвольном месте:

import numpy as np import matplotlib.pyplot as plt exno = 26 rg = np.random.Generator(np.random.PCG64(5)) x1 = rg.exponential(10, 5000) x2 = rg.normal(10, 0.1, 100) # Строим основную гистограмму plt.hist([x1, x2], bins=150, range=(0, 60), stacked=True) plt.minorticks_on() plt.xlim((0, 60)) plt.grid(which='major') plt.grid(which='minor', linestyle=':') # Строим вторую гистограмму в отдельных осях plt.axes([.5, .5, .4, .4]) plt.hist([x1, x2], bins=100, stacked=True, range=(9, 11)) plt.grid(which='major') plt.tight_layout() # сохраняем диаграмму в файл plt.savefig('histograms.png') plt.show() 

ex26

В этом примере была использована функция pyplot.savefig , сохраняющая содержимое текущего окна в файл в векторном или растровом формате. Формат задается с помощью аргумента format или автоматически определяется из имени файла (как в примере выше). Набор доступных форматов зависит от окружения, однако в большинстве случаев можно использовать такие форматы как png , jpeg , pdf , svg и eps .

Резюме

Предметом изучения в этом разделе был модуль pyplot библиотеки matplotlib , содержащий инструменты для построения различных диаграмм. Были рассмотрены:

  • функции для построения диаграмм pyplot.plot , pyplot.errorbar . pyplot.hist , pyplot.scatter , pyplot.contour и pyplot.contourf ;
  • средства настройки свойств линий и маркеров;
  • средства настройки координатных осей: подписи, размер шрифта, координатная сетка, произвольные метки др.;
  • инструмены для расположения нескольких координатных осей в одном окне.

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

Источники

  • matplotlib.pyplot
  • Pyplot tutorial
  • Colormaps
  • Scipy Lecture Notes

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *