[Python] Creating evenly spaced non-solid lines with colormap

Discussão em 'Python' iniciado por Stack, Agosto 6, 2025.

  1. Stack

    Stack Membro Participativo

    As an example I want to create a plot using z data as source for coloring using this code (modified from here:

    import warnings

    import matplotlib.pyplot as plt
    import numpy as np

    from matplotlib.collections import LineCollection


    def colored_line(x, y, c, ax, **lc_kwargs):
    if "array" in lc_kwargs:
    warnings.warn('The provided "array" keyword argument will be overridden')

    default_kwargs = {"capstyle": "butt"}
    default_kwargs.update(lc_kwargs)

    x = np.asarray(x)
    y = np.asarray(y)
    x_midpts = np.hstack((x[0], 0.5 * (x[1:] + x[:-1]), x[-1]))
    y_midpts = np.hstack((y[0], 0.5 * (y[1:] + y[:-1]), y[-1]))

    coord_start = np.column_stack((x_midpts[:-1], y_midpts[:-1]))[:, np.newaxis, :]
    coord_mid = np.column_stack((x, y))[:, np.newaxis, :]
    coord_end = np.column_stack((x_midpts[1:], y_midpts[1:]))[:, np.newaxis, :]
    segments = np.concatenate((coord_start, coord_mid, coord_end), axis=1)

    lc = LineCollection(segments, **default_kwargs)
    lc.set_array(c) # set the colors of each segment

    return ax.add_collection(lc)


    # -------------- Create and show plot --------------
    # Some arbitrary function that gives x, y, and color values
    t = np.linspace(-7.4, -0.5, 200)
    x = 0.9 * np.sin(t)
    y = 0.9 * np.cos(1.6 * t)
    color = np.linspace(0, 2, t.size)

    # Create a figure and plot the line on it
    fig1, ax1 = plt.subplots()
    lines = colored_line(x, y, color, ax1, linewidth=1, cmap="plasma",linestyle="dashed")
    fig1.colorbar(lines) # add a color

    # Set the axis limits and tick positions
    ax1.set_xlim(-1, 1)
    ax1.set_ylim(-1, 1)
    ax1.set_xticks((-1, 0, 1))
    ax1.set_yticks((-1, 0, 1))
    ax1.set_title("Color at each point")

    plt.show()


    # Create a figure and plot the line on it
    fig1, ax1 = plt.subplots()
    lines = colored_line(x, y, color, ax1, linewidth=1, cmap="plasma")
    fig1.colorbar(lines) # add a color
    ax1.plot(x,y, linestyle="dashed",color="white",linewidth=2,alpha=1)

    # Set the axis limits and tick positions
    ax1.set_xlim(-1, 1)
    ax1.set_ylim(-1, 1)
    ax1.set_xticks((-1, 0, 1))
    ax1.set_yticks((-1, 0, 1))
    ax1.set_title("Color at each point")

    plt.show()


    The first plot is the original approach adding the linestyle to the line collection leading to non-even spacing of the linestyle.

    Denser spacing at curvature

    The second is my simple approach of drawing the solid colored line and then drawing a white line on top of it creating even spacing. But this leads to problem in overlapping areas.

    Even spacing

    Is there a direct solution for my workaround that does not create funky new problems?

    Continue reading...

Compartilhe esta Página