1

I'm trying to get a different color for each point in this animation. I would like to pass the array c_state as the hue-value of a hsv-tuple for each point. So far everything I tried has failed. I've tried using this in the animate function:

particles.set_color(pbox.color[:,0],1.0,1.0)

But I'm getting warning that only length-1 arrays can be converted to scalars. I've also tried making length-3 arrays using np.random and trying to convert those to rgb-tuples but that didn't work either. I have trouble finding the right data-structure to pass to the color variable of ax.plot. The colors only have to be set once and don't need to change during the animation.

import matplotlib.pyplot as plt 
import matplotlib.animation as anim
import numpy as np
import colorsys
from random import random

n = 250

class ParticleBox:

    def __init__(self,i_state,c_state):
        self.i_state = np.asarray(i_state, dtype=float)
        self.c_state = np.asarray(c_state, dtype=float)

        self.state = self.i_state.copy()
        self.color = self.c_state.copy()

i_state = -5 + 10 * np.random.random((n, 2))
c_state = np.random.random((n, 1))

pbox = ParticleBox(i_state, c_state)

fig = plt.figure()
ax =  fig.add_subplot(111, xlim=(-10,10), ylim=(-10,10))

particles, = ax.plot([], [], 'o', ms=5)

def init():
    global pbox 
    particles.set_data([],[])

    return particles,

def animate(i):
    global pbox, ax, fig
    particles.set_data(pbox.state[:,0],pbox.state[:,1])

    return particles,

ani = anim.FuncAnimation(fig, animate, frames = 500, 
                         interval = 10, blit=True, 
                         init_func=init)
plt.show()
2
  • 1
    How has it failed, so far? Commented Mar 27, 2017 at 11:09
  • I've edited the question. Commented Mar 27, 2017 at 12:37

1 Answer 1

1

A line plot plt.plot() in matplotlib has exactly one color. You cannot set different colors to its segments.

What you need is a scatter plot plt.scatter. You can update a scatter plot using

sc = plt.scatter(x,y, c=.., s =.., cmap="hsv")
sc.set_offsets(np.c_[x,y]) # set positions
sc.set_array(color) # set color

color in this case would be a 1D array of values between 0 and 1. Those values would be mapped to hsv colors using the hsv colormap, which is specified in the cmap argument to scatter.

enter image description here

Complete code would look as follows:

import matplotlib.pyplot as plt 
import matplotlib.animation as anim
import numpy as np

n = 140

class ParticleBox:
    def __init__(self,i_state,c_state):
        self.i_state = np.asarray(i_state, dtype=float)
        self.c_state = np.asarray(c_state, dtype=float)
        self.state = self.i_state.copy()
        self.color = self.c_state.copy()
    def iterate(self):
        self.state += (np.random.random((n, 2))-0.5)/3.
        self.state[self.state > 10.] = 10
        self.state[self.state < -10] = -10
        self.color += (np.random.random(n)-0.5)/89.
        self.color[self.color>1.] = 1.
        self.color[self.color<0] = 0.


i_state = -5 + 10 * np.random.random((n, 2))
c_state = np.random.random(n)

pbox = ParticleBox(i_state, c_state)

fig = plt.figure()
ax =  fig.add_subplot(111, xlim=(-10,10), ylim=(-10,10))

particles = ax.scatter([], [], c=[],s=25, cmap="hsv", vmin=0, vmax=1)

def animate(i):
    pbox.iterate()
    particles.set_offsets(pbox.state)
    particles.set_array(pbox.color)
    return particles,

ani = anim.FuncAnimation(fig, animate, frames = 140, 
                         interval = 10, blit=True)

plt.show()
Sign up to request clarification or add additional context in comments.

3 Comments

Excellent, this is exactly what I was looking for! Thanks!
How I would go about making the size of the particles dynamic too? I've tried passing another 'set_array()' but that makes all the particles really small.
.set_array() determines the color. For the size use .set_sizes().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.