Заполнить область под кривой в 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')