Python Matplotlib-两个同心圆之间的填充区域

时间:2018-12-27 16:22:56

标签: python python-3.x matplotlib plot fill

我正在使用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_slemTrue时,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")

但是这种方法有两个问题:

  1. 如果更改了轴颜色,则第二次fill_between调用将基于white颜色产生错误的填充。
  2. 填充的区域相对于内圆看起来有点不对齐(有一个小的白色间隙),如下面的屏幕截图所示。

Plot

因此,我的问题来了:是否有更好,更精确的方法填充两个圆之间的区域,从而使我能够绕过这两个问题?

完全不相关的注释:可以在函数内调用mlp.show()吗?我不知道这里有什么最佳做法...也许最好返回图形手柄,让消费者决定何时弹出它?

1 个答案:

答案 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()

并导致不同的背景: enter image description here