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

Как нормировать гистограмму в python

  • автор:

Как нормализовать гистограмму pyplot?

Х​очу построить гистограмму распределения среднего выборки для экспоненциального распределения через pyplot hist. Параметр density выставил на True . Согласно документации, именно он должен нормализовать гистограмму к 1. Однако, результат мне непонятен:

expon_rv = sts.expon(loc = 0, scale = 1) sample = expon_rv.rvs(1000) n2 = 10 sample_2_mean = [] for k in range(1000): sample_2 = np.random.choice(sample, n2) sample_2_mean.append(np.mean(sample_2)) plt.hist(sample_2_mean, bins = 20, density = True) 

введите сюда описание изображения

Отслеживать
51.6k 199 199 золотых знаков 59 59 серебряных знаков 242 242 бронзовых знака
задан 29 июл 2021 в 13:19
1 1 1 бронзовый знак

не дочитали документацию: If stacked is also True, the sum of the histograms is normalized to 1. Или я не так понял ваше: нормализовать гистограмму к 1 ?

29 июл 2021 в 13:23
По сути мне нужна плотность распределения, по идее она не должна превышать, я про это
29 июл 2021 в 13:29
а почему вы решили, что площадь всех прямоугольников превышает 1? 😉
29 июл 2021 в 13:31
вообще никак, но мне нужно, чтобы отображалась доля
29 июл 2021 в 13:36
какая доля и чтобы как/где отображалась?
29 июл 2021 в 13:51

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

При указании параметра density=True — суммарная площадь прямоугольников будет равна единице. Т.е. вы получаете график плотности вероятностей. Если перемножить высоту на ширину каждого прямоугольника и сложить все полученные площади — мы должны получить 1.0 .

Отслеживать
ответ дан 29 июл 2021 в 14:11
MaxU — stand with Ukraine MaxU — stand with Ukraine
149k 12 12 золотых знаков 59 59 серебряных знаков 132 132 бронзовых знака

Я так понимаю, товарищу нужно что-то типа этого:

import numpy as np import matplotlib.pyplot as plt from matplotlib.ticker import PercentFormatter import scipy.stats as sts expon_rv = sts.expon(loc = 0, scale = 1) sample = expon_rv.rvs(1000) n2 = 10 sample_2_mean = [] for k in range(1000): sample_2 = np.random.choice(sample, n2) sample_2_mean.append(np.mean(sample_2)) weights = [x/sum(sample_2_mean) for x in sample_2_mean] plt.hist(sample_2_mean, bins = 20, weights=weights) plt.gca().yaxis.set_major_formatter(PercentFormatter(1)) #для отображения в процентах, а не в долях 

введите сюда описание изображения

Отслеживать
ответ дан 29 июл 2021 в 15:06
24.8k 4 4 золотых знака 20 20 серебряных знаков 36 36 бронзовых знаков

  • python
  • matplotlib
  • анализ-данных
  • статистика
  • гистограммы
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Вывести на экран гистограмму слов длиной более 3 символов из файла

В качестве аргумента командной строки поступает путь к файлу (или не поступает — тогда обрабатывать поток стандартного ввода).

Вывести на экран гистограмму слов длины > 3 в означенном файле следующего вида:

##### word1
################## word2
################################### word3
########## word4
Столбцы должны быть выровнены по левому краю. Максимальная длина записи гистограммы — 56 хешиков. Между хешиками и словом должны быть > 0 пробельных символов.

У меня есть код, который просто находит все слова, а сбоку пишет их количество

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
#! Программа подсчета слов в файле import os def get_words(filename): with open(filename, encoding="utf8") as file: text = file.read() text = text.replace("\n", " ") text = text.replace(",", "").replace(".", "").replace("?", "").replace("!", "") text = text.lower() words = text.split() words.sort() return words def get_words_dict(words): words_dict = dict() for word in words: if word in words_dict: words_dict[word] = words_dict[word] + 1 else: words_dict[word] = 1 return words_dict def main(): filename = input("Введите путь к файлу: ") if not os.path.exists(filename): print("Указанный файл не существует") else: words = get_words(filename) words_dict = get_words_dict(words) print("Кол-во слов: %d" % len(words)) print("Кол-во уникальных слов: %d" % len(words_dict)) print("Все использованные слова:") for word in words_dict: print(word.ljust(20), words_dict[word]) if __name__ == "__main__": main()

Хелпаните, чем сможете
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Вывести на экран в тестовом режиме гистограмму длиной 10 введенных с клавиатуры слов
Задача Программа которая выводит на экран в тестовом режиме гистограмму длиной 10 введенных с.

Вывести на экран все элементы заданного символьного массива Y$(8), длиной не более 5 символов
Вывести на экран все элементы заданного символьного массива Y$(8) длиной не более 5 символов.

Вывести на экран монитора горизонтально расположенную строку текста длиной не более десяти символов
Может кто-то помочь? Вывести на экран монитора горизонтально расположенную строку текста длиной.

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

Вывести на экран монитора горизонтально расположенную строку текста длиной не более десяти символов
Вывести на экран монитора горизонтально расположенную строку текста длиной не более десяти символов.

Эксперт Python

5415 / 3839 / 1214
Регистрация: 28.10.2013
Сообщений: 9,554
Записей в блоге: 1

1 2 3 4 5 6 7 8 9 10 11
from collections import Counter import re filename=r"gore-ot-uma.txt" with open(filename) as f: counter = Counter(re.findall('\w+',f.read())) for word,cnt in counter.most_common(): if len(word) > 3: if cnt >56: cnt = 56 print("#" * cnt, word) #print(("#" * cnt).ljust(60), word)

Как должны быть выровнены слова я так и не понял.
Регистрация: 11.07.2018
Сообщений: 96

Лучший ответ

Сообщение было отмечено Reywal как решение

Решение

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
import os def get_words(filename): """This function formats the text """ with open(filename, encoding = "ISO-8859-1") as file: text = file.read() text = text.replace("\n", " ") text = text.replace(",", "").replace(".", "").replace("?", "").replace("!", "").replace(";","").replace(":","") text = text.lower() words = text.split() return words def get_words_dict(words): """This functions writes words into the dictionary """ words_dict = dict() for word in words: if word in words_dict: words_dict[word] = words_dict[word] + 1 else: words_dict[word] = 1 return words_dict filename = input("Введите путь к файлу: ") if not os.path.exists(filename): print("Указанный файл не существует, введите строки","\n") words=list(eval(input())) else: words = get_words(filename) for x in set(words): if(len(x)>3 and words.count(x)56): print(''.format(words.count(x)*'#'),''.format(x))

Настраиваем формат отображения меток у координатных осей

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

с помощью которых часто делают сокрытие текстовых меток для тиков графика:

import numpy as np import matplotlib.pyplot as plt fig = plt.figure(figsize=(7, 4)) ax = fig.add_subplot() x = np.arange(-np.pi/2, np.pi, 0.1) ax.plot(x, np.sin(x)) ax.set_xticklabels([]) ax.set_yticklabels([]) ax.grid() plt.show()

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

Само форматирование осуществляется с помощью различных классов, расположенных в ветке:

И на этом занятии мы рассмотрим основные из них.

NullFormatter

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

from matplotlib.ticker import NullFormatter

А, затем, применить к оси абсцисс или ординат:

ax.xaxis.set_major_formatter(NullFormatter())

Мы здесь сначала обращаемся к объекту xaxis, отвечающий за ось Ox, и вызываем функцию set_major_formatter(), передавая ей экземпляр класса NullFormatter. В результате, подписи у этой оси исчезают и мы видим следующий результат:

По аналогии, можно работать и с осью ординат, только для этого следует использовать объект yaxis:

ax.yaxis.set_major_formatter(NullFormatter())

Увидим похожий результат, но уже для оси Oy.

FormatStrFormatter

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

ax.yaxis.set_major_formatter(FormatStrFormatter('%d'))

будет округлять все числа до целых и по оси Oy мы увидим следующее:

Если же указать спецификатор в виде:

ax.yaxis.set_major_formatter(FormatStrFormatter('%f'))

то получим вещественные числа с шестью знаками после запятой. Для управления точностью вещественных чисел используется запись вида:

ax.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))

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

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

ax.yaxis.set_major_formatter(FormatStrFormatter('y = %.2f'))

В итоге, перед каждым числом будет записано «y = ».

FuncFormatter

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

Для этого воспользуемся классом FuncFormatter и передадим ему ссылку на функцию formatOy:

ax.yaxis.set_major_formatter(FuncFormatter(formatOy))

Сама же функция будет выглядеть так:

def formatOy(x, pos): return f"[]" if x  0 else f"()"

Здесь x – это текущее значение риски; pos – текущая позиция (номер) риски от 0 до N, где N+1 – общее число рисок.

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

ScalarFormatter

Этот форматер используется пакетом matplotlib по умолчанию. Он отображает числовые данные так, как они есть с небольшими манипуляциями. Если число оказывается очень большим (больше 10^10), то его множитель выносится:

То же самое происходит и с очень маленькими числами (меньше 10^-10). Но мы можем изменить это поведение и настроить свой диапазон больших и малых значений. Например, если вывести график в диапазоне степени 10^5:

fig = plt.figure(figsize=(7, 4)) ax = fig.add_subplot() x = np.arange(-2*np.pi, 2*np.pi, 0.1) ax.plot(x, np.sinc(x) * 1e5) ax.grid() plt.show()

То числа будут отображены целиком без сокращений. Но, если сформировать ScalarFormatter и указать максимальную и минимальную степень 4:

sf = ScalarFormatter() sf.set_powerlimits((-4, 4)) ax.yaxis.set_major_formatter(sf)

то результат будет следующий:

Как видите, степень 10^5 была вынесена за скобки.

Если мы хотим настроить такое поведение глобально для всех графиков, то можно воспользоваться словарем rcParams и переопределить ключ axes.formatter.limits:

matplotlib.rcParams["axes.formatter.limits"] = (-4, 4)

FixedFormatter

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

ax.xaxis.set_major_locator(FixedLocator([-3, -2, -1, 0, 1, 2, 3])) ax.xaxis.set_major_formatter(FixedFormatter(['a', 'b', 'c', 'd', 'e', 'f', 'g']))

Причем, обратите внимание, мы использовали класс FixedFormatter совместно с классом FixedLocator, так как желательно, чтобы списки по длинам в этих классах совпадали.

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

Видео по теме

#1. Установка пакета и основные возможности

#2. Функция plot для построения и оформления двумерных графиков

#3. Отображение нескольких координатных осей в одном окне

#4. Граничные значения осей и локаторы для расположения меток на них

#5. Настраиваем формат отображения меток у координатных осей

#6. Делаем логарифмический масштаб у координатных осей

#7. Размещаем стандартные текстовые элементы на графике

#8. Добавляем легенду и рисуем геометрические фигуры на графиках

#9. Рисуем ступенчатые, стековые, stem и точечные графики

#10. Рисуем гистограммы, столбчатые и круговые диаграммы

#11. Показ изображений и цветовых сеток

#12. Как строить трехмерные графики

#13. Рисуем линии уровня функциями contour, contourf и tricontour, tricontourf

#14. Создаем анимацию графиков Классы FuncAnimation и ArtistAnimation

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

Способы создания гистограмм с помощью Python

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

Начнем с того, чего я сама по своей неопытности не знала очень долго: столбчатые диаграммы и гистограммы — разные вещи. Основное отличие состоит в том, что гистограмма показывает частотное распределение — мы задаем набор значений оси Ox, а по Oy всегда откладывается частота. В столбчатой диаграмме (которую в англоязычной литературе уместно было бы назвать barplot) мы задаем и значения оси абсцисс, и значения оси ординат.

Для демонстрации я буду использовать избитый набор данных библиотеки scikit learn Iris. Начнем c импортов:

import pandas as pd import numpy as np import matplotlib import matplotlib.pyplot as plt from sklearn import datasets iris = datasets.load_iris() 

Преобразуем набор данных iris в dataframe — так нам удобнее будет с ним работать в будущем.

data = pd.DataFrame(data= np.c_[iris['data'], iris['target']], columns= iris['feature_names'] + ['target']) 

Из интересующих нас параметров data содержит информацию о длине чашелистиков и лепестков и ширине чашелистиков и лепестков.

Используем Matplotlib
Построение гистограммы
Cтроим обычную гистограмму, показывающую частотное распределение длин лепестков и чашелистиков:

fig, axs = plt.subplots(1, 2) n_bins = len(data) axs[0].hist(data['sepal length (cm)'], bins=n_bins) axs[0].set_title('sepal length') axs[1].hist(data['petal length (cm)'], bins=n_bins) axs[1].set_title('petal length') 

image

Построение столбчатой диаграммы

Используем методы matplotlib-а, чтобы сравнить ширину листьев и чашелистиков. Это кажется удобнее всего делать на одном графике:

x = np.arange(len(data[:50])) width = 0.35 

Для примера и в целях упрощения картинки возьмем первые 50 строк dataframe.

fig, ax = plt.subplots(figsize=(40,5)) rects1 = ax.bar(x - width/2, data['sepal width (cm)'][:50], width, label='sepal width') rects2 = ax.bar(x + width/2, data['petal width (cm)'][:50], width, label='petal width') ax.set_ylabel('cm') ax.set_xticks(x) ax.legend()

image

Используем методы seaborn

На мой взгляд, многие задачи по построению гистограмм проще и эффективнее выполнять с помощью методов seaborn (кроме того, seaborn выигрывает еще и своими графическими возможностями, на мой взгляд).

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

sns_plot = sns.distplot(data['sepal width (cm)']) fig = sns_plot.get_figure() 

image

Если же вам необходим только график распределения, сделать его можно так:

snsplot = sns.kdeplot(data['sepal width (cm)'], shade=True) fig = snsplot.get_figure() 

image

Подробнее о построении распределений в seaborn можно почитать тут.

Pandas-гистограммы

Здесь все просто. На самом деле, это оболочка matplotlib.pyplot.hist(), но вызов функции через pd.hist() иногда удобнее менее поворотливых конструкций matplotlib-a. В документации библиотеки pandas можно прочитать больше.

Работает это так:

h = data['petal width (cm)'].hist() fig = h.get_figure() 

Спасибо, что прочитали до конца! Буду рада отзывам и комментариям!

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

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