Я рисую следующий график, используя Matplotlib
:
import matplotlib.pyplot as mlp
import numpy.linalg as npl
def ploteig(self, erg:bool) -> None:
theta = np.arange(start=0, stop=2.0*np.pi, step=0.01)
r = np.ones(len(theta))
values, _ = npl.eig(self._p)
values = values.astype(complex)
x_unit_circle = r * np.cos(theta)
y_unit_circle = r * np.sin(theta)
x_eigenvalues = np.unique(np.append(values, np.complex(1.0)))
y_eigenvalues = np.zeros(len(x_eigenvalues))
has_slem = False
if erg:
values_abs = np.sort(np.abs(values))
values_ct1 = np.isclose(values_abs, 1.0)
if not np.all(values_ct1):
mu = values_abs[~values_ct1][-1]
if not np.isclose(mu, 0.0):
r *= mu;
x_slem_circle = r * np.cos(theta)
y_slem_circle = r * np.sin(theta)
has_slem = True
fig, ax = mlp.subplots()
ax.plot(x_unit_circle, y_unit_circle, color='red', linestyle='-', linewidth=3)
ax.plot(x_eigenvalues, y_eigenvalues, color='blue', linestyle='None', marker='*', markersize=10)
if has_slem:
ax.plot(x_slem_circle, y_slem_circle, color='red', linestyle='--', linewidth=1)
ax.grid(True)
ax.set_aspect('equal', 'datalim')
mlp.show()
Если has_slem
равно True
, то круг Слеми всегда меньше единичного круга, поэтому на графике получается дваконцентрические круги, где внешний круг обозначен (x_unit_circle,y_unit_circle)
, а внутренний круг - (x_slem_circle,y_slem_circle)
.
Я хотел бы заполнить область между двумя кружками светло-красным цветом.Это то, что я пробовал до сих пор:
if has_slem:
ax.plot(x_slem_circle, y_slem_circle, color='red', linestyle='--', linewidth=1)
ax.fill_between(x_unit_circle, y_unit_circle, -y_unit_circle, color="red", alpha=0.2)
ax.fill_between(x_slem_circle, y_slem_circle, -y_slem_circle, color="white")
Но у этого подхода есть две проблемы:
- Если цвет осей изменится, второй вызов
fill_between
выдаст неправильныйЗаливка основана на white
цвете. - Заливная область выглядит немного смещенной относительно внутреннего круга (есть небольшой белый зазор), как вы можете видеть на скриншоте ниже.
Итак, вот мой вопрос: есть ли лучший и более точный подход для заполнения области между двумя кругами, который позволяет мне обойти обе проблемы?
На совершенно не связанной ноте: нормально ли вызывать mlp.show()
внутри функции?Я не знаю, какие здесь лучшие практики ... может быть, лучше вернуть дескриптор фигуры и позволить потребителю решить, когда его всплыть?