pyplot - tipos de plot python




python/matplotlib-linha multicolorida (2)

Estou tentando criar uma linha colorida com certas condições. Basicamente, gostaria de ter a linha colorida em vermelho ao apontar para baixo no eixo y, verde em apontar para cima e azul em nenhum dos dois.

Eu brinquei com alguns exemplos semelhantes que encontrei, mas nunca consegui convertê-los para trabalhar com plot () em um eixo. Apenas imaginando como isso poderia ser feito.

Aqui está um código que eu criei até agora:

#create x,y coordinates
x = numpy.random.choice(10,10)
y = numpy.random.choice(10,10)

#create an array of colors based on direction of line (0=r, 1=g, 2=b)
colors = []
#create an array that is one position away from original 
#to determine direction of line 
yCopy = list(y[1:])
for y1,y2 in zip(y,yCopy):
    if y1 > y2:
        colors.append(0)
    elif y1 < y2:
        colors.append(1)
    else:
        colors.append(2)
#add tenth spot to array as loop only does nine
colors.append(2)

#create a numpy array of colors
categories = numpy.array(colors)

#create a color map with the three colors
colormap = numpy.array([matplotlib.colors.colorConverter.to_rgb('r'),matplotlib.colors.colorConverter.to_rgb('g'),matplotlib.colors.colorConverter.to_rgb('b')])

#plot line
matplotlib.axes.plot(x,y,color=colormap[categories])

Não sei como obter plot () para aceitar uma matriz de cores. Sempre recebo um erro sobre o tipo de formato usado como a cor. Tentei heximal, decimal, string e float. Funciona perfeitamente com scatter ().

obrigado


ESTÁ BEM. Então, eu descobri como fazer isso usando o LineCollecion para desenhar a linha em um eixo.

import numpy as np
import pylab as pl
from matplotlib import collections  as mc

segments = []
colors = np.zeros(shape=(10,4))
x = range(10)
y = np.random.choice(10,10)
i = 0

for x1, x2, y1,y2 in zip(x, x[1:], y, y[1:]):
    if y1 > y2:
        colors[i] = tuple([1,0,0,1])
    elif y1 < y2:
        colors[i] = tuple([0,1,0,1])
    else:
        colors[i] = tuple([0,0,1,1])
    segments.append([(x1, y1), (x2, y2)])
    i += 1     

lc = mc.LineCollection(segments, colors=colors, linewidths=2)
fig, ax = pl.subplots()
ax.add_collection(lc)
ax.autoscale()
ax.margins(0.1)
pl.show()


Há um exemplo na página matplotlib mostrando como usar um LineCollection para plotar uma linha multicolorida.

O problema restante é obter as cores para a coleção de linhas. Portanto, se y são os valores a serem comparados,

cm = dict(zip(range(-1,2,1),list("gbr")))
colors = list( map( cm.get , np.sign(np.diff(y))  ))

Código completo:

import numpy as np; np.random.seed(5)
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

x = np.arange(10)
y = np.random.choice(10,10)

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

cm = dict(zip(range(-1,2,1),list("rbg")))
colors = list( map( cm.get , np.sign(np.diff(y))  ))

lc = LineCollection(segments, colors=colors, linewidths=2)
fig, ax = plt.subplots()
ax.add_collection(lc)

ax.autoscale()
ax.margins(0.1)
plt.show()







matplotlib