Гистограмма ошибок python

Improve Article

Save Article

Like Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Like Article

    In this article we will see how we can create a error bar graph in the PyQtGraph module. PyQtGraph is a graphics and user interface library for Python that provides functionality commonly required in designing and science applications. Its primary goals are to provide fast, interactive graphics for displaying data (plots, video, etc.). Error bars are graphical representations of the variability of data and used on graphs to indicate the error or uncertainty in a reported measurement. They give a general idea of how precise a measurement is, or conversely, how far from the reported value the true value might be.
     

    We can create a plot window and create error bar graph on it with the help of commands given below.

    # creating a pyqtgraph plot window
    plt = pg.plot()
    
    # creating a error bar item object
    error = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5)

    In order to create a error bar graph in pyqtgraph we have to do the following 
    1. Import the pyqtgraph module 
    2. import other modules as well like numpy and pyqt5 
    3. Create a main window class 
    4. Create a plot window and error bar item 
    5. Set x-axis, y-axis and upper and lower error values to the error bar item 
    6. Create a grid layout 
    7. Add error bar item to the plot window and plot the data on plot window 
    8. Add plot window and additional label to the layout 
    9. Set layout widget as the central widget
     

    Below is the implementation 

    Python3

    from PyQt5.QtWidgets import *

    import sys

    import numpy as np

    import pyqtgraph as pg

    from PyQt5.QtGui import *

    from PyQt5.QtCore import *

    from collections import namedtuple

    class Window(QMainWindow):

        def __init__(self):

            super().__init__()

            self.setWindowTitle("PyQtGraph")

            self.setGeometry(100, 100, 600, 500)

            icon = QIcon("skin.png")

            self.setWindowIcon(icon)

            self.UiComponents()

            self.show()

        def UiComponents(self):

            widget = QWidget()

            label = QLabel("Geeksforgeeks Error Bar plot")

            label.setWordWrap(True)

            pg.setConfigOptions(antialias=True)

            x = np.arange(10)

            y = np.arange(10) % 3

            top = np.linspace(1.0, 3.0, 10)

            bottom = np.linspace(2, 0.5, 10)

            plt = pg.plot()

            error = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5)

            plt.addItem(error)

            plt.plot(x, y, symbol='o', pen={'color': 0.8, 'width': 2})

            layout = QGridLayout()

            label.setMinimumWidth(130)

            widget.setLayout(layout)

            layout.addWidget(label, 1, 0)

            layout.addWidget(plt, 0, 1, 3, 1)

            self.setCentralWidget(widget)

    App = QApplication(sys.argv)

    window = Window()

    sys.exit(App.exec())

    Output :
     

    Last Updated :
    18 Nov, 2021

    Like Article

    Save Article

    • Редакция Кодкампа

    17 авг. 2022 г.
    читать 2 мин


    Часто вам может быть интересно добавить планки погрешностей к диаграммам в Python, чтобы отразить неопределенность измерений или вычисленных значений. К счастью, это легко сделать с помощью библиотеки matplotlib.

    В этом руководстве объясняется, как добавить планки погрешностей как в гистограммы, так и в линейные диаграммы в Python.

    Планки погрешностей в гистограммах

    Предположим, у нас есть следующий набор данных из 10 значений в Python:

    import numpy as np
    import matplotlib.pyplot as plt
    
    #define dataset
    data = [4, 6, 6, 8, 9, 14, 16, 16, 17, 20]
    

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

    Стандартная ошибка = с / √n

    куда:

    • s: стандартное отклонение выборки
    • n: размер выборки

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

    #calculate standard error
    std_error = np.std(data, ddof=1) / np.sqrt(len(data))
    
    #view standard error 
    std_error
    
    1.78
    

    Наконец, мы можем создать гистограмму, используя полосы погрешностей, ширина которых равна стандартной ошибке:

    #define chart 
    fig, ax = plt.subplots()
    
    #create chart
    ax.bar(x=np.arange(len(data)), #x-coordinates of bars
     height=data, #height of bars
     yerr=std_error, #error bar width
     capsize=4) #length of error bar caps 
    

    Гистограмма с планками погрешностей в Python

    Стандартная ошибка оказалась равной 1,78.Это ширина полосы погрешности, которая простирается в обоих направлениях от точечных оценок на графике. Например, значение первого столбца на диаграмме равно 4, поэтому он имеет полосу погрешности, которая простирается от:

    • Нижний конец: 4 – 178 = 2,22
    • Верхний предел: 4 + 1,78 = 5,78

    Каждая полоса ошибок на диаграмме имеет одинаковую ширину.

    Планки погрешностей в линейных диаграммах

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

    import numpy as np
    import matplotlib.pyplot as plt
    
    #define data
    data = [4, 6, 6, 8, 9, 14, 16, 16, 17, 20]
    
    #define x and y coordinates
    x = np.arange(len(data))
    y = data
    
    #create line chart with error bars
    fig, ax = plt.subplots()
    
    ax.errorbar(x, y,
     yerr=std_error,
     capsize=4) 
    

    Линейная диаграмма с планками погрешностей в Python

    Обратите внимание, что аргумент yerr указывает Python создавать вертикальные планки погрешностей. Вместо этого мы могли бы использовать горизонтальные вертикальные полосы, используя аргумент xerr :

    #create line chart with horizontal error bars
    fig, ax = plt.subplots()
    
    ax.errorbar(x, y,
     xerr =std_error,
     capsize=4) 
    

    Планки погрешностей в диаграмме Python

    Вы можете найти больше руководств по Python здесь .

    I want to plot a histogram with points and error bars. I do not want bar or step histograms. Is this possible? Google has not helped me, I hope you can. Also it should not be normalized. Thanks!

    ali_m's user avatar

    ali_m

    71.3k23 gold badges221 silver badges296 bronze badges

    asked Oct 7, 2013 at 10:40

    Abhinav Kumar's user avatar

    Abhinav KumarAbhinav Kumar

    1,5635 gold badges19 silver badges33 bronze badges

    0

    Assuming you’re using numpy and matplotlib, you can get the bin edges and counts using np.histogram(), then use pp.errorbar() to plot them:

    import numpy as np
    from matplotlib import pyplot as pp
    
    x = np.random.randn(10000)
    counts,bin_edges = np.histogram(x,20)
    bin_centres = (bin_edges[:-1] + bin_edges[1:])/2.
    err = np.random.rand(bin_centres.size)*100
    pp.errorbar(bin_centres, counts, yerr=err, fmt='o')
    
    pp.show()
    

    enter image description here

    I’m not sure what you mean by ‘normalized’, but it would be easy to, for example, divide the counts by the total number of values so that the histogram sums to 1.

    The bigger question for me is what the errorbars would actually mean in the context of a histogram, where you’re dealing with absolute counts for each bin.

    answered Oct 7, 2013 at 11:05

    ali_m's user avatar

    You can also do this in pure Matplotlib, using matplotlib.pyplot.hist to draw the histogram.

    import numpy as np               # Only used to generate the data
    import matplotlib.pyplot as plt
    
    x = np.random.randn(1000)
    
    plt.figure()
    
    # Matplotlib's pyplot.hist returns the bin counts, bin edges,
    # and the actual rendered blocks of the histogram (which we don't need)
    bin_counts, bin_edges, patches = plt.hist(x, bins=30)
    bin_centres = (bin_edges[:-1] + bin_edges[1:]) / 2
    
    # Generate some dummy error values, of the same dimensions as the bin counts
    y_error = np.random.rand(bin_counts.size)*10
    
    # Plot the error bars, centred on (bin_centre, bin_count), with length y_error
    plt.errorbar(x=bin_centres, y=bin_counts,
                 yerr=y_error, fmt='o', capsize=2)
    
    plt.show()
    

    Histogram figure with error bars

    answered Nov 27, 2021 at 16:58

    theo-brown's user avatar

    theo-browntheo-brown

    57110 silver badges25 bronze badges

    Автор оригинала: Team Python Pool.

    В этой статье мы узнаем о панели ошибок Matplotlib в Python. Модуль Pyplot библиотеки Matplotlib предоставляет интерфейс, подобный MATLAB. А функция matplotlib.pyplot.errorbar() выводит y против x в виде линий и/или маркеров с прикрепленными полосами ошибок. Кроме того, полосы ошибок помогают указать предполагаемую ошибку или неопределенность, чтобы дать общее представление о том, насколько точны измерения; это делается с помощью маркеров, нарисованных поверх исходного графика и его точек данных. Прежде чем мы рассмотрим примеры Matplotlib errorbar и гистограмм ошибок, позвольте мне кратко рассказать вам о синтаксисе и вернуть то же самое.

    Синтаксис matplotlib errorbar()

    matplotlib.pyplot.errorbar(x, y,,, fmt=",,,,,,,,,,, *,, **kwargs)

    Параметры панели ошибок Matplotlib:

    • x, y: Горизонтальные и вертикальные координаты точек данных.
    • fmt: Содержит строковое значение (необязательно)
    • xerr, yerr: Массив, содержащий ошибки, и ошибки должны быть положительными значениями.
    • ecolor: (по умолчанию: NONE) Простыми словами, это цвет линий errorbar. (Необязательно)
    • elinewidth: Linewidth строк errorbar со значением по умолчанию NONE. (Необязательно)
    • capsize: Длина заглавных букв строки ошибок в точках со значением по умолчанию NONE. (Необязательно)
    • barsabove: (по умолчанию: False)Содержит логические значения для построения баров ошибок над символами графика. (Необязательно)
    • lolims, uplims, xlolims, xuplims: Содержит логические значения, которые указывают, что значение дает только верхние/нижние пределы. (Необязательно) errorevery: Содержит целочисленные значения, которые помогают рисовать полосы ошибок на подмножестве данных. (Необязательно)

    Возвращаемый тип Matplotlib Errorbar:

    Функция Matplotlib errorbar() возвращает контейнер, имеющий: plotline: Line2D экземпляр маркеров x, y plot и/или line. caplines: Кортеж Line2D экземпляров шапки бара ошибок. barlinecols: Кортеж LineCollection с горизонтальным и вертикальным диапазонами ошибок.

    Пример Matplotlib Errorbar в Python

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

    import numpy as np 
    import matplotlib.pyplot as plt 
      .arange(0.1, 4, 0.5) .exp(-xval) 
      
    plt.errorbar(xval, yval,.4,.5) 
      
    plt.title('matplotlib.pyplot.errorbar() function Example') 
    plt.show()

    ВЫХОД:

    Пример Matplotlib Errorbar в PythonПример Matplotlib Errorbar в Python

    ОБЪЯСНЕНИЕ:

    Во-первых, приведенный выше пример является фундаментальной реализацией функции Matplotlib errorbar (). “xval” и “yval” содержат горизонтальные и вертикальные координаты точек данных, необходимых для построения диаграммы ошибок. Кроме того, “xerr” и “yerr” являются аргументами функции errorbar. Присвоенные им значения равны 0,4 и 0,5, соответственно, положительным значениям погрешности. Наконец, эти четыре параметра, переданные функции error bar (), являются обязательными аргументами, необходимыми для построения любых ошибок Python.

    Matplotlib Errorbar в Python Несколько строк

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

    import numpy as np 
    import matplotlib.pyplot as plt 
       .figure() .arange(10)  * np.sin(x / 20 * np.pi) .linspace(0.05, 0.2, 10) 
       
    plt.errorbar(x, y + 7,, 
                ) 
    plt.errorbar(x, y + 5,, 
                ,  
                ) 
    plt.errorbar(x, y + 3,,  
                ,  
                , 
                ) 
      
    upperlimits = [True, False] * 5
    lowerlimits = [False, True] * 5
    plt.errorbar(x, y,, 
                ,  
                , 
                ) 
       ) 
      
    plt.title('matplotlib.pyplot.errorbar() 
    function Example') 
    plt.show()

    ВЫХОД:

    Панель ошибок в Python Несколько строкПанель ошибок в Python Несколько строк

    ОБЪЯСНЕНИЕ:

    Во-первых, в приведенном выше примере функция matplotlib errorbar() создает несколько строк errorbar. Определенные x и y являются координатами точек данных. Вдоль оси y – ошибка построения графика. Следовательно, для каждой строки указывается только “yerr”. Кроме того, верхний и нижний пределы указывают значения только для верхнего и нижнего пределов. Кроме того, метка является аргументом, указывающим строки как строка 1, строка 2 и т. Д.

    Гистограмма ошибок с ошибкой в x

    import matplotlib.pyplot as plt  
      
    # making a simple plot 
    x =[1, 2, 3, 4, 5, 6, 7] 
    y =[1, 2, 1, 2, 1, 2, 1] 
      
    # creating error .5
      
    # ploting graph 
    plt.plot(x, y) 
    plt.errorbar(x, y, 
                , 
                )

    ВЫХОД:

    Гистограмма ошибок с ошибкой в xГистограмма ошибок с ошибкой в x

    ОБЪЯСНЕНИЕ:

    Во-первых, в приведенном выше примере x и y-это массивы, определенные с координатами x и y для построения графика. Кроме того, “x_error” равен 0,5, что приводит к ошибкам только вдоль оси x. X, y и xers являются обязательными параметрами, передаваемыми в панель ошибок Matplotlib в Python. Также передается необязательный параметр ‘fmt’, содержащий строковое значение.

    Гистограмма ошибок с ошибкой в вашем

    import matplotlib.pyplot as plt  
      
      
    # making a simple plot 
    x =[1, 2, 3, 4, 5, 6, 7] 
    y =[1, 2, 1, 2, 1, 2, 1] 
      
    # creating error .2
      
    # ploting graph 
    plt.plot(x, y) 
      
    plt.errorbar(x, y, 
                , 
                )

    ВЫХОД:

    Гистограмма ошибок с ошибкой в вашемГистограмма ошибок с ошибкой в вашем

    ОБЪЯСНЕНИЕ:

    Во-первых, в приведенном выше примере x и y-это массивы, определенные с координатами x и y для построения графика. Значение “y_error” равно 0,2, что приводит к ошибкам только вдоль оси y. X, y и yerr являются обязательными параметрами, передаваемыми функции errorbar. Также передается необязательный параметр ‘fmt’, содержащий строковое значение.

    Гистограмма ошибок с переменной ошибкой в x и y

    import matplotlib.pyplot as plt 
      
    x =[1, 2, 3, 4, 5] 
    y =[1, 2, 1, 2, 1] 
      
    y_errormin =[0.1, 0.5, 0.9, 
                 0.1, 0.9] 
    y_errormax =[0.2, 0.4, 0.6,  
                 0.4, 0.2] 
      .5
    y_error =[y_errormin, y_errormax] 
      
    # ploting graph 
    # plt.plot(x, y) 
    plt.errorbar(x, y, 
                , 
                ,  
                )

    ВЫХОД:

    Гистограмма ошибок с переменной ошибкой в x и yГистограмма ошибок с переменной ошибкой в x и y

    ОБЪЯСНЕНИЕ:

    В приведенном выше примере показан график гистограммы ошибок для переменных ошибок. Аналогично, x и y-это два массива, определенные, содержащие координатные точки. Ошибка по оси x равна 0,5. Одновременно ошибка по оси y между двумя массивами равна y_errormin и y_errormax. Эти параметры являются аргументами функции Matplotlib errorbar для получения желаемого результата.

    Вывод

    Эта статья наглядно представляет вам различные способы использования панели ошибок Matplotlib в Python. Примеры как штриховых линий ошибок, так и графиков приведены с подробным объяснением. Полосы ошибок обеспечивают дополнительный уровень детализации представленных данных. Обратитесь к этой статье для любых запросов, связанных с функцией Matplotlib errorbar ().

    Однако, если у вас есть какие-либо сомнения или вопросы, дайте мне знать в разделе комментариев ниже. Я постараюсь помочь вам как можно скорее.

    Счастливого Пифонирования!

    Время на прочтение
    11 мин

    Количество просмотров 31K

    Визуализация одномерных данных в Python

    Построение графика одной переменной кажется простой задачей. Но насколько это просто в действительности — эффективно отобразить данные со всего одним измерением? Долгое время я обходился стандартной гистограммой, которая показывает расположение значений, разброс и форму распределения данных (нормальное, скошенное, двухпиковое и др). Но недавно я столкнулся со случаем, когда гистограмма не помогла. И тогда понял, что настало время узнать больше о построении графиков. Я нашёл в сети отличную бесплатную книгу о визуализации данных и попробовал некоторые методы. Я решил, что (и мне, и другим людям) будет полезно, если я поделюсь этими знаниями и составлю руководство по построению на Python гистограмм и их крайне полезной альтернативы — графиков распределения плотности (density plots). Подробности — к старту нашего курса по анализу данных.

    Я подробно рассмотрю применение гистограмм и графиков распределения в Python при помощи библиотек matplotlib и seaborn. На протяжении всего руководства исследуем набор реальных данных, потому что богатство доступных в сети материалов не даёт права отказываться от них! Покажем данные NYCflights13 с более чем 300000 наблюдений за авиарейсами из Нью-Йорка в 2013 году. Сосредоточимся на отображении одной переменной — задержки прибытия рейсов в минутах. Весь код этой статьи — в Jupyter Notebook на GitHub.

    Перед построением графика всегда полезно изучить данные. Считаем данные во фрейм данных pandas и отобразим первые 10 строк:

    import pandas as pd
    # Read in data and examine first 10 rows
    flights = pd.read_csv('data/formatted_flights.csv')
    flights.head(10)

    Задержки рейсов указаны в минутах. Отрицательные значения означают, что самолёт совершил посадку с опережением графика (они часто его опережают в те самые дни, когда мы никуда не летим!) Всего у нас более 300000 рейсов. Наименьшая задержка составляет минус шестьдесят минут, наибольшая — сто двадцать минут. В другом столбце — названия авиалиний для сравнения.

    Гистограммы

    Разумно начать изучение данных с построения гистограммы. При построении гистограммы переменная делится на бины, точки данных подсчитываются в каждом бине, эти бины откладываются по оси x. По оси y откладывается число объектов. Здесь бины отражают диапазон времени задержки рейса, а по y откладывается число рейсов, попавшее в этот интервал. Важнейший параметр гистограммы — ширина бина (binwidth). Всегда стоит попробовать разную ширину и выбрать самую подходящую.

    В Python базовую гистограмму может построить или matplotlib, или seaborn. В приведённом ниже коде показаны вызовы функций в обеих библиотеках, которые создают эквивалентные графики. При вызове функции plot мы указываем ширину бина, выраженную в числе бинов. Для этого графика я использую бины длиной 5 минут, что означает, что количество бинов будет равно диапазону данных (от -60 до 120 минут), делённому на ширину бина, 5 минут (bins = int(180/5)).

    # Import the libraries
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    # matplotlib histogram
    plt.hist(flights['arr_delay'], color = 'blue', edgecolor = 'black',
             bins = int(180/5))
    
    # seaborn histogram
    sns.distplot(flights['arr_delay'], hist=True, kde=False, 
                 bins=int(180/5), color = 'blue',
                 hist_kws={'edgecolor':'black'})
    # Add labels
    plt.title('Histogram of Arrival Delays')
    plt.xlabel('Delay (min)')
    plt.ylabel('Flights')

    Для базовых гистограмм я использовал бы код matplotlib, поскольку он проще. Но в нашем примере для создания разных распределений мы воспользуемся функцией seaborn distplot. Она хорошо подходит для знакомства с разными вариантами.

    Почему я взял за ширину бина 5 минут? Чтобы найти оптимальное значение, нужно попробовать разные варианты! Ниже я привожу код для создания такого же графика в matplotlib с различными значениями ширины бина. В конечном счёте нет верного или неверного ответа на вопрос о его ширине. Я выбрал 5 минут, потому что считаю, что это значение лучше всего отражает распределение.

    # Show 4 different binwidths
    for i, binwidth in enumerate([1, 5, 10, 15]):
    
        # Set up the plot
        ax = plt.subplot(2, 2, i + 1)
    
        # Draw the plot
        ax.hist(flights['arr_delay'], bins = int(180/binwidth),
                 color = 'blue', edgecolor = 'black')
    
        # Title and labels
        ax.set_title('Histogram with Binwidth = %d' % binwidth, size = 30)
        ax.set_xlabel('Delay (min)', size = 22)
        ax.set_ylabel('Flights', size= 22)
    
    plt.tight_layout()
    plt.show()

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

    Когда гистограммы бесполезны

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

    (Заметим, что ось y нормализована с учётом различий в количестве рейсов разных авиалиний. Для этого мы используем аргумент norm_hist = True при вызове функции sns.distplot).

    Пользы от такого графика мало! Перекрытие линий делает сравнение авиалиний практически невыполнимой задачей. Рассмотрим варианты решения этой задачи.

    Вариант 1. Сравнительные гистограммы (Side-by-Side Histograms)

    Вместо наложения гистограмм друг на друга мы можем расположить их рядом. Для этого создадим списки (list) задержек рейсов по авиалиниям, а затем передадим вызываемой функции plt.hist список таких списков. Разным авиалиниям мы присвоим разные цвета (color) и наименования (name), чтобы их проще было отличить друг от друга. Всё это, начиная с создания списков, делает вот такой код:

    # Make a separate list for each airline
    x1 = list(flights[flights['name'] == 'United Air Lines Inc.']['arr_delay'])
    x2 = list(flights[flights['name'] == 'JetBlue Airways']['arr_delay'])
    x3 = list(flights[flights['name'] == 'ExpressJet Airlines Inc.']['arr_delay'])
    x4 = list(flights[flights['name'] == 'Delta Air Lines Inc.']['arr_delay'])
    x5 = list(flights[flights['name'] == 'American Airlines Inc.']['arr_delay'])
    
    # Assign colors for each airline and the names
    colors = ['#E69F00', '#56B4E9', '#F0E442', '#009E73', '#D55E00']
    names = ['United Air Lines Inc.', 'JetBlue Airways', 'ExpressJet Airlines Inc.'',
             'Delta Air Lines Inc.', 'American Airlines Inc.']
    
    # Make the histogram using a list of lists
    # Normalize the flights and assign colors and names
    plt.hist([x1, x2, x3, x4, x5], bins = int(180/15), normed=True,
             color = colors, label=names)
    
    # Plot formatting
    plt.legend()
    plt.xlabel('Delay (min)')
    plt.ylabel('Normalized Flights')
    plt.title('Side-by-Side Histogram with Multiple Airlines')

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

    Вариант 2. Столбчатые графики (Stacked Bars)

    Вместо построения столбцов данных рядом мы можем расположить их друг над другом при помощи параметра stacked = True при вызове гистограммы:

    # Stacked histogram with multiple airlines
    plt.hist([x1, x2, x3, x4, x5], bins = int(180/15), stacked=True,
             normed=True, color = colors, label=names)

    Этот вариант ничуть не лучше! В каждом бине представлены доли всех авиалиний, однако сравнить их всё ещё невозможно. Вот например, у кого больше доля в бине от -15 до 0 минут: у United Air Lines или же у JetBlue Airlines? Я этого пока не знаю и аудитория тоже. И вообще, я не фанат столбчатых диаграмм. Они обычно трудны для понимания. (Полезными они могут быть лишь в отдельных случаях, например при визуализации соотношений). Ни один из этих гистограммных графиков не приблизил нас к решению. Настало время попробовать графики распределения.

    Графики распределения (Density Plots)

    Для начала — что это за графики? График распределения можно назвать непрерывным сглаженным аналогом гистограммы. Самый распространённый вариант построения такого графика — ядерная оценка плотности. В этом методе для каждой точки данных строится непрерывная кривая — ядро. Все эти кривые складываются вместе, чтобы получить единую гладкую оценку плотности. Чаще всего используется гауссово ядро (которое даёт колоколообразную кривую Гаусса в каждой точке данных). Если вы, как и я, находите это описание немного запутанным, взгляните на следующий график:

    Ядерная оценка плотности (Источник)

    Каждый чёрный вертикальный штрих у оси x представляет точку данных. Отдельные ядра (в данном случае — гауссовы) построены над каждой точкой красными пунктирными линиями. Их суммирование даёт общий график распределения, показанный сплошной синей линией.

    По оси x здесь, как и на гистограмме, откладывается значение переменной. Но что показывает ось y? Ось y на графике плотности — это функция плотности вероятности для ядерной оценки плотности. Нужно помнить, что это именно плотность вероятности, а не сама вероятность. Разница между ними заключается в том, что плотность вероятности — это вероятность на единицу по оси x. Для преобразования этих данных в обычную вероятность нам нужно найти площадь под кривой для определённого интервала на оси x. Несколько смущает то, что поскольку это плотность вероятности, а не вероятность, ось y может принимать значения больше единицы. Единственное требование к графику плотности — чтобы общая площадь под кривой интегрировалась в единицу. Я привык рассматривать ось y на графике распределения как величину, применимую только для относительных сравнений между категориями.

    Графики распределения в Seaborn

    При построении графиков распределения в seaborn можно использовать функцию distplot или kdeplot. Я снова использую distplot, ведь он строит несколько распределений одним вызовом функции. Например, можно построить график распределения задержек всех рейсов поверх соответствующей гистограммы:

    # Density Plot and Histogram of all arrival delays
    sns.distplot(flights['arr_delay'], hist=True, kde=True, 
                 bins=int(180/5), color = 'darkblue', 
                 hist_kws={'edgecolor':'black'},
                 kde_kws={'linewidth': 4})

    График распределения и гистограмма, построенные при помощи seaborn

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

    У графика распределения есть величина, аналогичная ширине бина в гистограмме. Её называют шириной полосы пропускания (bandwidth). Эта величина позволяет изменить отдельные ядра и значительно влияет на общий вид графика. Библиотека построения графиков (plotting library) позволяет выбрать ширину полосы пропускания (по умолчанию используется «оценка по Скотту» (scott)). В отличие от гистограмм здесь я обычно полагаюсь на значение по умолчанию. Тем не менее ничто не мешает нам попробовать разную ширину полосы и выбрать оптимальную. Значение по умолчанию на этом графике, ‘scott’, действительно выглядит как наилучший вариант.

    График распределения плотностей, показывающий различные полосы пропускания

    Заметим, что с увеличением полосы пропускания распределение становится более сглаженным. Мы также видим, что, несмотря на ограничение данных от -60 до 120 минут, график плотности выходит за эти пределы. Это одна из возможных проблем графика плотности. Поскольку мы строим распределение в каждой точке данных, генерируемые данные могут выходить за рамки исходного диапазона. Таким образом, мы получаем на оси x нереалистичные значения, которых не было в исходном наборе данных! Мы также можем изменить ядро, что, в свою очередь, изменит распределение в каждой точке. Тем не менее в большинстве случаев ядро Гаусса по умолчанию и стандартная оценка полосы пропускания работают хорошо.

    Вариант 3. График распределения

    Теперь мы знаем, что представляет собой график распределения плотностей. Посмотрим, поможет ли он визуализировать задержки рейсов разных авиалиний. Чтобы показать эти распределения на одном графике, мы можем перебрать все авиалинии, каждый раз вызывая distplot. При этом мы присвоим параметру kde (kernel density estimate, ядерная оценка плотности) значение True, а параметру hist (гистограмма) — значение False. Код для построения графика распределения для множества авиалиний приведён ниже:

    # List of five airlines to plot
    airlines = ['United Air Lines Inc.', 'JetBlue Airways', 'ExpressJet Airlines Inc.'',
             'Delta Air Lines Inc.', 'American Airlines Inc.']
    
    # Iterate through the five airlines
    for airline in airlines:
        # Subset to the airline
        subset = flights[flights['name'] == airline]
    
        # Draw the density plot
        sns.distplot(subset['arr_delay'], hist = False, kde = True,
                     kde_kws = {'linewidth': 3},
                     label = airline)
    
    # Plot formatting
    plt.legend(prop={'size': 16}, title = 'Airline')
    plt.title('Density Plot with Multiple Airlines')
    plt.xlabel('Delay (min)')
    plt.ylabel('Density')

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

    Графики распределения с затенением (Shaded Density Plots)

    Заполнение графика распределения плотностей позволяет нам различать перекрывающиеся распределения. Этот подход не всегда оправдан, но он может подчеркнуть разницу распределений. Чтобы затенять графики плотности, мы передаём shade = True в аргументе kde_kws при вызове функции distplot.

    sns.distplot(subset['arr_delay'], hist = False, kde = True,
                     kde_kws = {'shade': True, 'linewidth': 3}, 
                      label = airline)

    Затенять или не затенять — вот в чём вопрос… И ответ на него зависит от решаемой задачи! В нашем случае затенение не лишено смысла, поскольку помогает нам рассмотреть оба графика в области их перекрытия. Наконец, мы получили полезную информацию: рейсы Alaska Airlines показывают тенденцию к опережению графика чаще, чем United Airlines. Теперь вы знаете, чьи рейсы выбирать!

    Штрих-диаграммы (Rug Plots)

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

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

    Она показывает каждую точку на оси x и визуализирует все исходные значения. Преимущество использования distplot в seaborn — возможность добавления штрих-диаграммы при вызове rug = True с одним параметром (и небольшим форматированием).

    # Subset to Alaska Airlines
    subset = flights[flights['name'] == 'Alaska Airlines Inc.']
    
    # Density Plot with Rug Plot
    sns.distplot(subset['arr_delay'], hist = False, kde = True, rug = True,
                 color = 'darkblue', 
                 kde_kws={'linewidth': 3},
                 rug_kws={'color': 'black'})
    
    # Plot formatting
    plt.title('Density Plot with Rug Plot for Alaska Airlines')
    plt.xlabel('Delay (min)')
    plt.ylabel('Density')

    Если точек данных много, штрих-диаграмма становится слишком сложной, однако она полезна в некоторых проектах, так как позволяет увидеть каждую точку данных. Штрих-диаграмма также наглядно показывает, как график распределения «создаёт» данные там, где их нет. Это связано с распределением ядерной оценки плотности в каждой точке данных. Это распределение может выходить за рамки начального диапазона данных, создавая впечатление, что некоторые рейсы Alaska Airlines прибывают и раньше и позже, чем в действительности. Нужно помнить об этой иллюзии и информировать о ней аудиторию!

    Заключение

    Смею надеяться, что в этом посте я перечислил набор полезных для вас вариантов визуализации значений одной переменной для одной и более категорий. Мы могли бы построить и другие одномерные («однопеременные») графики: эмпирические графики кумулятивной плотности (empirical cumulative density plots) и графики квантиль-квантиль (quantile-quantile plots). Однако в этой статье остановимся на гистограммах и графиках распределения (со штрих-диаграммами!). Если даже эти варианты кажутся вам слишком сложными, не отчаивайтесь. После некоторой практики вам станет проще сделать правильный выбор. Если потребуется, вы всегда можете обратиться за помощью. Более того, часто оптимального выбора не существует, а «верное» решение зависит и от личных предпочтений, и от цели визуализации данных. Но, какой бы график вы ни выбрали, вы всегда сможете построить его же Python! Визуальная подача доходчива, а зная все возможные варианты, мы всегда сможем выбрать наилучший график для нашего набора данных.

    Любая обратная связь и конструктивная критика приветствуются. Меня можно найти в Twitter @koehrsen_will.

    Научим вас аккуратно работать с данными, чтобы вы прокачали карьеру и стали востребованным IT-специалистом:

    • Профессия Data Analyst
    • Профессия Data Scientist (24 месяца)

    Понравилась статья? Поделить с друзьями:

    Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Гисметео ошибка 502
  • Гис тэк ошибка при проверке цепочки сертификатов
  • Гис гмп ошибка 503
  • Гис гмп ошибка 502

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии