Как сделать одну линию затухающей с помощью pyplot? [Дубликат]

Btw, если вы не задаете длину, по умолчанию будет 255 (проверено в MySQL)

26
задан Community 14 November 2012 в 04:51
поделиться

5 ответов

Недавно я ответил на вопрос с похожим запросом (, создав более 20 уникальных цветов легенды, используя matplotlib ). Там я показал, что вы можете отобразить цикл цветов, который вам нужен, чтобы выстроить линии на цветную карту. Вы можете использовать ту же процедуру для получения определенного цвета для каждой пары точек.

Вы должны выбрать цветовую карту осторожно, потому что цветовые переходы вдоль вашей линии могут оказаться резкими, если цветная карта цветная.

В качестве альтернативы вы можете изменить альфа каждого сегмента линии в диапазоне от 0 до 1.

. В приведенном ниже примере кода есть подпрограмма (highResPoints), чтобы развернуть номер точек вашего случайного блуждания, потому что, если у вас слишком мало очков, переходы могут показаться резкими. Этот бит кода был вдохновлен еще одним недавним ответом, который я дал: https://stackoverflow.com/a/8253729/717357

import numpy as np
import matplotlib.pyplot as plt

def highResPoints(x,y,factor=10):
    '''
    Take points listed in two vectors and return them at a higher
    resultion. Create at least factor*len(x) new points that include the
    original points and those spaced in between.

    Returns new x and y arrays as a tuple (x,y).
    '''

    # r is the distance spanned between pairs of points
    r = [0]
    for i in range(1,len(x)):
        dx = x[i]-x[i-1]
        dy = y[i]-y[i-1]
        r.append(np.sqrt(dx*dx+dy*dy))
    r = np.array(r)

    # rtot is a cumulative sum of r, it's used to save time
    rtot = []
    for i in range(len(r)):
        rtot.append(r[0:i].sum())
    rtot.append(r.sum())

    dr = rtot[-1]/(NPOINTS*RESFACT-1)
    xmod=[x[0]]
    ymod=[y[0]]
    rPos = 0 # current point on walk along data
    rcount = 1 
    while rPos < r.sum():
        x1,x2 = x[rcount-1],x[rcount]
        y1,y2 = y[rcount-1],y[rcount]
        dpos = rPos-rtot[rcount] 
        theta = np.arctan2((x2-x1),(y2-y1))
        rx = np.sin(theta)*dpos+x1
        ry = np.cos(theta)*dpos+y1
        xmod.append(rx)
        ymod.append(ry)
        rPos+=dr
        while rPos > rtot[rcount+1]:
            rPos = rtot[rcount+1]
            rcount+=1
            if rcount>rtot[-1]:
                break

    return xmod,ymod


#CONSTANTS
NPOINTS = 10
COLOR='blue'
RESFACT=10
MAP='winter' # choose carefully, or color transitions will not appear smoooth

# create random data
np.random.seed(101)
x = np.random.rand(NPOINTS)
y = np.random.rand(NPOINTS)

fig = plt.figure()
ax1 = fig.add_subplot(221) # regular resolution color map
ax2 = fig.add_subplot(222) # regular resolution alpha
ax3 = fig.add_subplot(223) # high resolution color map
ax4 = fig.add_subplot(224) # high resolution alpha

# Choose a color map, loop through the colors, and assign them to the color 
# cycle. You need NPOINTS-1 colors, because you'll plot that many lines 
# between pairs. In other words, your line is not cyclic, so there's 
# no line from end to beginning
cm = plt.get_cmap(MAP)
ax1.set_color_cycle([cm(1.*i/(NPOINTS-1)) for i in range(NPOINTS-1)])
for i in range(NPOINTS-1):
    ax1.plot(x[i:i+2],y[i:i+2])


ax1.text(.05,1.05,'Reg. Res - Color Map')
ax1.set_ylim(0,1.2)

# same approach, but fixed color and 
# alpha is scale from 0 to 1 in NPOINTS steps
for i in range(NPOINTS-1):
    ax2.plot(x[i:i+2],y[i:i+2],alpha=float(i)/(NPOINTS-1),color=COLOR)

ax2.text(.05,1.05,'Reg. Res - alpha')
ax2.set_ylim(0,1.2)

# get higher resolution data
xHiRes,yHiRes = highResPoints(x,y,RESFACT)
npointsHiRes = len(xHiRes)

cm = plt.get_cmap(MAP)

ax3.set_color_cycle([cm(1.*i/(npointsHiRes-1)) 
                     for i in range(npointsHiRes-1)])


for i in range(npointsHiRes-1):
    ax3.plot(xHiRes[i:i+2],yHiRes[i:i+2])

ax3.text(.05,1.05,'Hi Res - Color Map')
ax3.set_ylim(0,1.2)

for i in range(npointsHiRes-1):
    ax4.plot(xHiRes[i:i+2],yHiRes[i:i+2],
             alpha=float(i)/(npointsHiRes-1),
             color=COLOR)
ax4.text(.05,1.05,'High Res - alpha')
ax4.set_ylim(0,1.2)



fig.savefig('gradColorLine.png')
plt.show()

На этом рисунке показаны четыре случая:

enter image description here [/g2]

21
ответ дан Community 23 August 2018 в 19:21
поделиться

Слишком долго для комментария, поэтому просто хотел подтвердить, что LineCollection намного быстрее, чем подсегменты для строки по линии.

метод LineCollection намного быстрее в моих руках .

# Setup
x = np.linspace(0,4*np.pi,1000)
y = np.sin(x)
MAP = 'cubehelix'
NPOINTS = len(x)

Мы проверим итеративный график по методу LineCollection выше.

%%timeit -n1 -r1
# Using IPython notebook timing magics
fig = plt.figure()
ax1 = fig.add_subplot(111) # regular resolution color map
cm = plt.get_cmap(MAP)
for i in range(10):
    ax1.set_color_cycle([cm(1.*i/(NPOINTS-1)) for i in range(NPOINTS-1)])
    for i in range(NPOINTS-1):
        plt.plot(x[i:i+2],y[i:i+2])

1 loops, best of 1: 13.4 s per loop

%%timeit -n1 -r1 
fig = plt.figure()
ax1 = fig.add_subplot(111) # regular resolution color map
for i in range(10):
    colorline(x,y,cmap='cubehelix', linewidth=1)

1 loops, best of 1: 532 ms per loop

Ускоренная выборка вашей линии для лучшего цветового градиента, как показывает выбранный вами ответ, по-прежнему является хорошей идеей, если вы хотите гладкий градиент, и у вас есть только несколько точек.

5
ответ дан alexbw 23 August 2018 в 19:21
поделиться

Я использовал код @alexbw для построения параболы. Он работает очень хорошо. Я могу изменить набор цветов для функции. Для вычисления мне потребовалось около 1 мин и 30 секунд. Я использовал Intel i5, графику 2gb, 8GB RAM.

Код следующий:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.collections as mcoll
import matplotlib.path as mpath

x = np.arange(-8, 4, 0.01)
y = 1 + 0.5 * x**2

MAP = 'jet'
NPOINTS = len(x)

fig = plt.figure()
ax1 = fig.add_subplot(111) 
cm = plt.get_cmap(MAP)
for i in range(10):
    ax1.set_color_cycle([cm(1.0*i/(NPOINTS-1)) for i in range(NPOINTS-1)])
    for i in range(NPOINTS-1):
        plt.plot(x[i:i+2],y[i:i+2])

plt.title('Inner minimization', fontsize=25)
plt.xlabel(r'Friction torque $[Nm]$', fontsize=25)
plt.ylabel(r'Accelerations energy $[\frac{Nm}{s^2}]$', fontsize=25)
plt.show() # Show the figure

И результат: https://i.stack.imgur.com/gL9DG.png

0
ответ дан Djordje Vukcevic 23 August 2018 в 19:21
поделиться

Я добавил свое решение, используя pcolormesh. Каждый сегмент линии рисуется с использованием прямоугольника, который интерполирует между цветами на каждом конце. Поэтому он действительно интерполирует цвет, но мы должны пройти толщину линии.

import numpy as np
import matplotlib.pyplot as plt

def colored_line(x, y, z=None, linewidth=1, MAP='jet'):
    # this uses pcolormesh to make interpolated rectangles
    xl = len(x)
    [xs, ys, zs] = [np.zeros((xl,2)), np.zeros((xl,2)), np.zeros((xl,2))]

    # z is the line length drawn or a list of vals to be plotted
    if z == None:
        z = [0]

    for i in range(xl-1):
        # make a vector to thicken our line points
        dx = x[i+1]-x[i]
        dy = y[i+1]-y[i]
        perp = np.array( [-dy, dx] )
        unit_perp = (perp/np.linalg.norm(perp))*linewidth

        # need to make 4 points for quadrilateral
        xs[i] = [x[i], x[i] + unit_perp[0] ]
        ys[i] = [y[i], y[i] + unit_perp[1] ]
        xs[i+1] = [x[i+1], x[i+1] + unit_perp[0] ]
        ys[i+1] = [y[i+1], y[i+1] + unit_perp[1] ]

        if len(z) == i+1:
            z.append(z[-1] + (dx**2+dy**2)**0.5)     
        # set z values
        zs[i] = [z[i], z[i] ] 
        zs[i+1] = [z[i+1], z[i+1] ]

    fig, ax = plt.subplots()
    cm = plt.get_cmap(MAP)
    ax.pcolormesh(xs, ys, zs, shading='gouraud', cmap=cm)
    plt.axis('scaled')
    plt.show()

# create random data
N = 10
np.random.seed(101)
x = np.random.rand(N)
y = np.random.rand(N)
colored_line(x, y, linewidth = .01)

enter image description here [/g0]

2
ответ дан spacether 23 August 2018 в 19:21
поделиться

Обратите внимание, что если у вас много точек, вызов plt.plot для каждого сегмента линии может быть довольно медленным. Более эффективно использовать объект LineCollection.

Используя рецепт colorline , вы можете сделать следующее:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.collections as mcoll
import matplotlib.path as mpath

def colorline(
    x, y, z=None, cmap=plt.get_cmap('copper'), norm=plt.Normalize(0.0, 1.0),
        linewidth=3, alpha=1.0):
    """
    http://nbviewer.ipython.org/github/dpsanders/matplotlib-examples/blob/master/colorline.ipynb
    http://matplotlib.org/examples/pylab_examples/multicolored_line.html
    Plot a colored line with coordinates x and y
    Optionally specify colors in the array z
    Optionally specify a colormap, a norm function and a line width
    """

    # Default colors equally spaced on [0,1]:
    if z is None:
        z = np.linspace(0.0, 1.0, len(x))

    # Special case if a single number:
    if not hasattr(z, "__iter__"):  # to check for numerical input -- this is a hack
        z = np.array([z])

    z = np.asarray(z)

    segments = make_segments(x, y)
    lc = mcoll.LineCollection(segments, array=z, cmap=cmap, norm=norm,
                              linewidth=linewidth, alpha=alpha)

    ax = plt.gca()
    ax.add_collection(lc)

    return lc


def make_segments(x, y):
    """
    Create list of line segments from x and y coordinates, in the correct format
    for LineCollection: an array of the form numlines x (points per line) x 2 (x
    and y) array
    """

    points = np.array([x, y]).T.reshape(-1, 1, 2)
    segments = np.concatenate([points[:-1], points[1:]], axis=1)
    return segments

N = 10
np.random.seed(101)
x = np.random.rand(N)
y = np.random.rand(N)
fig, ax = plt.subplots()

path = mpath.Path(np.column_stack([x, y]))
verts = path.interpolated(steps=3).vertices
x, y = verts[:, 0], verts[:, 1]
z = np.linspace(0, 1, len(x))
colorline(x, y, z, cmap=plt.get_cmap('jet'), linewidth=2)

plt.show()

enter image description here [/g1]

15
ответ дан unutbu 23 August 2018 в 19:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: