Заполнить область под кривой в python matlibplot на шкале журнала
Я пытаюсь заполнить область под кривой matplotlib. script ниже работает отлично.
import matplotlib.pyplot as plt
from math import sqrt
x = range(100)
y = [sqrt(i) for i in x]
plt.plot(x,y,color='k',lw=2)
plt.fill_between(x,y,0,color='0.8')
plt.show()
Однако, если я задал y-масштаб логарифмическим (см. ниже). Он иногда заполняет область над кривой! Может кто-нибудь мне помочь? Я хотел бы заполнить область между кривой и y = 0.
x = range(100)
y = [sqrt(i) for i in x]
plt.plot(x,y,color='k',lw=2)
plt.fill_between(x,y,0,color='0.8')
plt.yscale('log')
plt.show()
Спасибо заранее!
Ответы
Ответ 1
С логарифмической y-шкалой fill_between(x, y, 0)
сообщает matplotlib заполнить область между log(0) = -infinity
и log(y)
. Естественно, это не работает. Вы можете избежать проблемы, изменив 0
на некоторое небольшое число, например 1e-6
.
Ответ 2
Как уже упоминалось, 0 -> -inf
в шкале журнала. Таким образом, любое построенное значение, которое было меньше или равно нулю, было бы проблематичным (требуя бесконечного ylim в лог-пространстве). Эта проблема существует независимо от того, используете ли вы fill_between() или нет.
К счастью, matplotlib обеспечивает удобный способ справиться с этим. В поведении по умолчанию matplotlib маскирует значения каждого значения, меньшего или равного нулю. В вашем примере это означает, что вся ваша строка y=0
замаскирована и исключена из многоугольника, определяющего заполненную область. В результате многоугольник просто закрывается, рисуя линию от (100,10)
вниз и влево до (0,0)
. Другой вариант - скопировать значения. В этом случае они устанавливаются на 1e-300
и не рассматриваются при определении ylim графика. Чтобы получить желаемый результат, сделайте следующее:
plt.yscale('log', nonposy='clip')