Skip to content Skip to sidebar Skip to footer

Filling The Area Between Archimedes Spyrals With Interpolated Colours - Matplotlib

I want to plot various spirals like the ones shown in the Figure (one spiral inner the others). Let's say I have three spirals (S1, S2 and S3) and I want to fill the area between c

Solution 1:

You could draw many spirals close to each other, in the range from 0 to 2 pi. (2 pi is the distance between the successive rings.)

Note that a color value as '0.20' (a string of a number) corresponds to a grey value of 0.20, where 0 is black and 1 is white.

Also note that plt.fill_between() supposes the x-values are ordered, which isn't the case.

To obtain a fully filled spiral, you could add a start angle to your equation as shown in the central subplot. The right subplot uses an interpolation between two colors.

import numpy as np
import matplotlib.pyplot as plt


defcreate_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 inzip(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.8if ax == axes[0] else1, 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 inzip(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

Solution 2:

I get a solution for filling properly between S1 and S3. As for the gradient, fill_btween or fill_betweenx require either same set of x or y, which is not your case. For gradient, @JohanC 's approximation is nice.

import numpy as np
import matplotlib.pyplot as plt

defcreate_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)

You have to be careful about constructing the polygon to fill, only part of x2 and y2 are selected.

enter image description here

Post a Comment for "Filling The Area Between Archimedes Spyrals With Interpolated Colours - Matplotlib"