2017-03-20 2 views
1

Je travaille donc avec un capteur de couleur TCS3200 et Arduino Mega 2560 pour générer des valeurs RVB spécifiques. Puis, à travers le câble série, j'envoie des données à VIDLE pour Python, en séparant les 3 points de données, et en les stockant dans un tableau (mise à jour du graphe MatPlotLib tous les 50 points de données (par RGB).)MatPlotLib Python - Valeurs RVB du capteur de couleur utilisé pour changer la couleur du point de ligne

traçait les valeurs R, G, B sur trois lignes séparées ... maintenant je trace une ligne différente, basée sur un système de coordonnées (255,255,255) (y-limit est 255 * sqrt (3)). Ce que je veux faire est ceci: si mes valeurs de RVB sont (220, 60, 140), je veux pouvoir changer la couleur du point de données basé sur ces valeurs. Le point du graphe serait sqrt (pow (220,2.0) + pow (60,2.0) + pow (140,2.0)), mais la couleur doit refléter la valeur RGB.

Comment faire?

Voici ma configuration actuelle du terrain:

import serial 
import numpy as np 
import matplotlib.pyplot as plt 
from drawnow import * 

distance = [] 
s = serial.Serial(port='/dev/cu.usbmodem1421', baudrate=115200) 
plt.ion() 
cnt = 0 
limit = 255*sqrt(3); 
r = 0 
g = 0 
b = 0 

def makeFig(): 
     plt.ylim(0,limit) 
     plt.title('My Live Streaming Sensor Data') 
     plt.grid(True) 
     plt.ylabel('RGB Values') 
     plt.xlabel('Time') 
     # somewhere in the line below I think the RGB dynamics should be reflected 
     plt.plot(distance, '-', label='Distance') 
     plt.ticklabel_format(useOffset=True) 
     plt.legend(loc='upper left') 

while True: 
     while (s.inWaiting()): 
       myDataString = s.readline() 
       try: 
         dataArray = myDataString.split(',') 
         print (dataArray) 
         r = float(dataArray[0]) 
         g = float(dataArray[1]) 
         b = float(dataArray[2]) 
         d = float(dataArray[3].strip('\r\n') 
         distance.append(d) 
         # before this 'drawnow' gets called, should the RGB values be incorporated into the plot? 
         drawnow(makeFig) 
         plt.pause(0.000001) 
         cnt = cnt + 1 
         if (cnt > 50): 
           distance.pop(0) 
       except ValueError: 
         print (myDataString) 
+0

Voir cet article sur créer des exemples reproductibles: http://stackoverflow.com/help/mcve Tant que cet exemple repose sur ce mystérieux paquet 'drawnow', personne ne va être capable de vous aider. –

+0

(même chose pour la fiabilité d'un port série pour les données, mock avec une instance 'StringIO' d'un fichier CSV) –

+0

' drawnow' est le paquet le plus inutile que j'ai jamais vu. Il se compose littéralement de 'plt.clf()', suivi de l'appel de la fonction, et 'plt.draw()'. Mais je suis d'accord qu'un [mcve] devrait être fourni en posant une question comme celle-ci. – ImportanceOfBeingErnest

Répondre

1

est ici un moyen de tracer des points au niveau des positions correspondant à la distance de l'origine dans le cube RVB. Leur couleur sera définie sur le tuple de valeur rgb.

import numpy as np 
import matplotlib.pyplot as plt 

# Mockup Serial 
class Serial(): 
    n = 0 
    def __init__(self, **kwargs): 
     self.maxN = kwargs.get("maxN", 1000) 
     self.cols = np.arange(0,240,1) 
    def inWaiting(self): 
     self.n+=1 
     return (self.n<self.maxN) 
    def readline(self): 
     a = np.random.choice(self.cols,size=3) 
     a = list(map(str, a)) 
     b = str(np.random.randint(0,10)) 
     return ",".join(a)+","+b+'\r\n' 

distance = [] 
colors = [] 
s = Serial(port='/dev/cu.usbmodem1421', baudrate=115200) 
plt.ion() 
cnt = 0 
limit = 255.*np.sqrt(3) 
r = 0 
g = 0 
b = 0 


plt.ylim(0,limit) 
plt.title('My Live Streaming Sensor Data') 
plt.grid(True) 
plt.ylabel('RGB Values') 
plt.xlabel('Time') 

line, = plt.plot([],[], '-', color="gray",label='Distance') 
scatter = plt.scatter([],[], s=40, marker='o', label='Hit', zorder=3) 
plt.ticklabel_format(useOffset=True) 
plt.legend(loc='upper left') 


while (s.inWaiting()): 
    myDataString = s.readline() 
    dataArray = myDataString.split(',') 
    r = int(dataArray[0]) 
    g = int(dataArray[1]) 
    b = int(dataArray[2]) 
    d = int(dataArray[3].strip('\r\n')) 
    distance.append(np.sqrt(r**2+b**2+g**2)) 
    color = (r/255.,g/255.,b/255.) 
    colors.append(color) 
    x = range(len(distance)) 
    line.set_data(x, distance) 
    scatter.set_offsets(np.c_[x,distance]) 
    scatter.set_color(colors) 
    plt.xlim(min(x), max(x)) 
    plt.pause(0.01) 
    cnt = cnt + 1 
    if (cnt > 50): 
     distance.pop(0) 
     colors.pop(0) 
    plt.draw() 

enter image description here

+0

Je peux produire ce graphique ci-dessus, il a l'air vraiment bien. Cependant, disons que l'axe des ordonnées est de 255 * sqrt (3) (qui est la longueur maximale/diagonale d'un cube RGB (255,255,255)), est-ce que je pourrais rendre ces couleurs différentes en fonction de la valeur RVB temps on est tracée? –

+0

Souhaitez-vous que tous les points changent de couleur une fois qu'un nouveau point est tracé? – ImportanceOfBeingErnest

+0

Pas vraiment. Alors disons que le premier point tracé est basé sur RGB (120,60,100) ... sa valeur sur l'axe y est ~ 167, alors le point suivant est (120,80,110) ... y-axis ~ 181 .... .la ligne créée par les points est une pente positive mais les points eux-mêmes sont la couleur représentée par leur valeur RVB. Si cela est stupide, alors je pourrais envisager de mettre un cercle de taille décente en haut à droite du graphique, qui agit comme l'affichage des couleurs. –