用插值颜色Matplotlib填充阿基米德spyrals之间的区域

2024-09-30 00:40:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我想绘制各种螺旋,如图中所示(一个螺旋在另一个螺旋内)。假设我有三个螺旋线(S1,S2和S3),我想填充连续螺旋线之间的区域,即S1和S2,S2和S3之间的区域,最后是S3和S1之间的区域

Three spirals

我尝试了几种方法来解决以下两个问题,但都没有成功:

1-一对螺旋线之间的区域应涂上插值颜色。例如,第一个螺旋(S1)为黑色,第二个螺旋(S2)为灰色,则S1和S2之间的区域必须是从黑色到灰色的渐变

2-S3和S1之间的区域未按我的要求填充。这里,填充的区域在S1和S3之间,而不是S3和S1之间

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt

def create_archimides_spiral(a=0, b=1, num_spirals=10):

    """
    Functions that creates an archimides spiral
    """

    th = np.linspace(0, num_spirals*np.pi, num_spirals*100) # The higher the number of splits, the greater the quality of each segment

    r = a + b*th

    x = r * np.cos(th)
    y = r * np.sin(th)

    return x, y

# create the spirals
x, y = create_archimides_spiral(a=0,b=1)
x1, y1 = create_archimides_spiral(a=2, b=1)
x2, y2 = create_archimides_spiral(a=4, b=1)

fig, ax = plt.subplots(1)
ax.plot(x, y, color='black', linewidth=3)
ax.plot(x1, y1, color='gray', linewidth=3)
ax.plot(x2, y2, color='silver', linewidth=3)

plt.fill(
    np.append(x, x1[::-1]),
    np.append(y, y1[::-1]), color= "lightgray"
)

plt.fill(
   np.append(x1, x2[::-1]),
   np.append(y1, y2[::-1]), color= "lightgray"
)

plt.fill_between(x, y, y1, interpolate=True)
plt.fill_between(x1, y, y1, interpolate=True)

ax.set_aspect(1)
plt.show()

这是我得到的数字,但这不是我想要的

Filled areas

如果能在这方面得到任何帮助,我将不胜感激

最佳再培训

奥斯卡


Tags: 区域s3createnppltaxcolorx1
2条回答

我得到了一个在S1和S3之间正确填充的解决方案。至于梯度,fill_btweenfill_betweenx需要相同的x或y集,这不是您的情况。对于梯度,@JohanC的近似很好

import numpy as np
import matplotlib.pyplot as plt

def create_archimides_spiral(a=0, b=1, num_spirals=10):

    """
    Functions that creates an archimides spiral
    """

    th = np.linspace(0, num_spirals*np.pi, num_spirals*100) # The higher the number of splits, the greater the quality of each segment

    r = a + b*th

    x = r * np.cos(th)
    y = r * np.sin(th)

    return x, y, r

# create the spirals
x, y, r= create_archimides_spiral(a=0,b=1)
x1, y1, r1 = create_archimides_spiral(a=2, b=1)
x2, y2, r2 = create_archimides_spiral(a=4, b=1)

fig, ax = plt.subplots(1)
ax.plot(x, y, color='black', linewidth=3)
ax.plot(x1, y1, color='gray', linewidth=3)
ax.plot(x2, y2, color='silver', linewidth=3)

ax.fill_between(np.concatenate((x, x1[::-1])), np.concatenate((y, y1[::-1])), color= "red", interpolate=True)

ax.fill(np.concatenate((x1, x2[::-1])), np.concatenate((y1, y2[::-1])), color= "blue")

ax.fill(np.concatenate([x[::-1], x2[0:800]]), np.concatenate([y[::-1], y2[0:800]]), color= "cyan")

ax.set_aspect(1)

在构造要填充的多边形时必须小心,仅选择x2和y2的一部分

enter image description here

您可以在0到2π的范围内绘制许多彼此靠近的缓和曲线。(2 pi是连续环之间的距离。)

注意,作为'0.20'(一个数字字符串)的颜色值对应于0.20的灰色值,其中0为黑色1为白色

还要注意plt.fill_between()假设x值是有序的,但事实并非如此

要获得完全填充的缓和曲线,可以向方程式中添加起始角度,如中心子图所示。右侧子地块使用两种颜色之间的插值

import numpy as np
import matplotlib.pyplot as plt


def create_archimides_spiral(a=0, b=1, start_angle=0, num_spirals=10):
    th = np.linspace(0, num_spirals * np.pi, num_spirals * 100)
    r = a + b * th
    x = r * np.cos(th + start_angle)
    y = r * np.sin(th + start_angle)
    return x, y


fig, axes = plt.subplots(ncols=3)
for ax, largest_a in zip(axes, [2 * np.pi, 2 * np.pi, 1.5 * np.pi]):
    a_values = np.linspace(0, largest_a, 100)
    grey_values = np.linspace(0, 0.8 if ax == axes[0] else 1, 100)
    if ax == axes[1]:
        cmap = plt.cm.inferno
    elif ax == axes[2]:
        cmap = plt.cm.colors.LinearSegmentedColormap.from_list('', ['crimson', 'skyblue'])
    for a, grey in zip(a_values, grey_values):
        if ax == axes[1]:
            x, y = create_archimides_spiral(a=0, b=1, start_angle=a)
        else:
            x, y = create_archimides_spiral(a=a, b=1, start_angle=0)
        ax.plot(x, y, color=f'{grey:.3f}' if ax == axes[0] else cmap(grey))
    ax.set_aspect('equal')
plt.show()

comparing three plots

相关问题 更多 >

    热门问题