我正在使用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
时,slem圆始终小于单位圆,因此图产生两个同心圆,其中外圆由(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()
吗?我不知道这里有什么最佳做法...也许最好返回图形手柄,让消费者决定何时弹出它?
答案 0 :(得分:1)
pyplot.contourf
是您要寻找的。可能会这样:
# inner radius
inner = 0.5
# the two circles
thetas = np.linspace(0,2*np.pi, 200)
# you don't need r = np.one(len(thetas))
x_unit_circle = np.cos(thetas)
y_unit_circle = np.sin(thetas)
x_eigens = x_unit_circle * inner
y_eigens = y_unit_circle * inner
xs = np.linspace(-1.1,1.1, 201)
ys = np.linspace(-1.1,1.1, 201)
# mesh for contours
xv,yv = np.meshgrid(xs,ys)
# generate the level map
r = xv**2 + yv**2
pyplot.figure(figsize=(8,8))
# plot the contours with two levels only
# notice the xv, yv parameters
pyplot.contourf(xv, yv, r, levels=[inner**2,1], colors=('r','g','b'))
# plot the two circles
pyplot.plot(x_unit_circle, y_unit_circle, color='b', linewidth=3)
pyplot.plot(x_eigens, y_eigens, color='g', linewidth=3, linestyle='--')
pyplot.show()