Обрезка/обрезка линий и заливка в matplotlib на морском дистрибутиве kde-function

Скажем, я использую seaborn для построения распределения, его медианы и стандартного отклонения, например:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Get data
data = np.random.randn(6000)

# Compute statistics
median = np.median(data)
sigma = np.std(data)

low = median - sigma
hi = median + sigma

# Plot
sns.distplot(data)
plt.axvline(median, c='r')
plt.axvline(low, c='k')
plt.axvline(hi, c='k')

Обрезка/обрезка линий и заливка в matplotlib на морском дистрибутиве kde-function

Как мне «обрезать» или «обрезать» строки, чтобы они отображались только под kde-функцией distplot? В результате должно получиться что-то вроде этого (быстро делается с помощью gimp):

Обрезка/обрезка линий и заливка в matplotlib на морском дистрибутиве kde-function

Бонусный вопрос: как мне сделать то же самое с plt.fill_between(), чтобы была заполнена только область под кривой? Я думаю, что мне не хватает чего-то легкого здесь. Я уже обрезал вызовы fill_between к другим элементам раньше, но я не знаю, как получить координаты функции и как это сделать с помощью линий.

Есть ли простой и лаконичный способ сделать то, что я хочу?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
699
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Хитрость здесь заключается в том, чтобы получить значение x, ближайшее к low, median и high, а затем использовать plt.ylines вместо plt.axvline, чтобы построить вертикальную линию от y = 0 до желаемого значения y.

# Plot
ax = sns.distplot(data)
x, y = ax.get_lines()[0].get_data()
plt.vlines(median, 0, y[np.argmin(abs(x-median))], color='r')
plt.vlines(low, 0, y[np.argmin(abs(x-low))], color='k')
plt.vlines(hi, 0, y[np.argmin(abs(x-hi))], color='k')
plt.show()

Ответ принят как подходящий

Один из способов сделать это — найти данные, соответствующие гладкой линии, которую kdeplot добавляет к графику, и использовать ее координаты x и y.

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

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.interpolate import interp1d

# Get data
data = np.random.randn(6000)

# Compute statistics
median = np.median(data)
sigma = np.std(data)

low = median - sigma
hi = median + sigma

ax = sns.distplot(data)
# get the line that sns uses for kdeplot; at this point in the code 
# there is only one line; if there are more we need to exract the correct
# one.
line = ax.lines[0].get_data()
# To get y for x=low, x=high and x=median we can interpolate the line data
ipf = interp1d(x=line[0], y=line[1])

ax.plot([low, low], [0, ipf(low)])
ax.plot([hi, hi], [0, ipf(hi)])
ax.plot([median, median], [0, ipf(median)]);

Line to kdeplot

Мы можем использовать данные линии в качестве входных данных для fill_between.

plt.fill_between(line[0], np.zeros(len(line[0])), line[1]);

Line to kdeplot and fill_between

Надеюсь это поможет.

Другие вопросы по теме