9

I have a series of lines (currently 60 in total) that I want to plot to the same figure to show the time evolution of a certain process. The lines currently are plotted so that the earliest time step is plotted in 100% red, the latest time step is plotted in 100% blue, and the time steps in the middle are some mixture of red and blue based on what time they are at (the amount of red decreases linearly with increasing time, while the amount of blue increases linearly with increasing time; a simple color gradient). I would like to make a (preferably vertical) color bar of some kind that shows this in a continuous fashion. What I mean by that is I want a color bar that is red on the bottom, blue on the top, and some mixture of red and blue in the middle of the bar that smoothly transitions from red to blue in the same manner as the lines I plot. I also want to put axes on this color bar so that I can show which color corresponds to which timestep.

I've read the documentation for matplotlib.pyplot.colorbar() but wasn't able to figure out how to do what I wanted to do without using one of matplotlib's previously defined colormaps. My guess is that I'll need to define my own colormap that transitions from red to blue and then it will be relatively simple to feed that to matplotlib.pyplot.colorbar() and get the color bar that I want.

Here is an example of the code I use to plot the lines:

import numpy as np
from matplotlib import pyplot as pp

x= ##x-axis values for plotting

##start_time is the time of the earliest timestep I want to plot, type int
##end_time is the time of the latest timestep I want to plot, type int

for j in range(start_time,end_time+1):
    ##Code to read data in from time step number j
    y = ##the data I want to plot
    red = 1. - (float(j)-float(start_time))/(float(end_time)-float(start_time))
    blue = (float(j)-float(start_time))/(float(end_time)-float(start_time))
    pp.plot(bin_center,spectrum,color=(red,0,blue))
pp.show()

EDIT:

Maybe this will make it clearer what I mean. Below is my figure: My figure

Each line shows the relation between the x-values and the y-values at a different time step. The red lines are earlier time steps, the blue lines are later time steps, and the purple lines are in the middle, as I defined above. With this already plotted, how would I create a color bar (vertically on the right side if possible) mapping the colors of the lines (continuously) to the time value of the time step each color represents?

NeutronStar
  • 2,057
  • 7
  • 31
  • 49
  • Have a look at the answer to this [question](http://stackoverflow.com/questions/16834861/create-own-colormap-using-matplotlib-and-plot-color-scale) – The Dude Sep 09 '14 at 15:27
  • @TheDude There is too much going on that I don't understand in the answer that it's impossible for me to know how to translate it to my problem. – NeutronStar Sep 09 '14 at 19:23

1 Answers1

16

There are two things that you need to do here.

  1. Create a red to blue color map, because that isn't one of the standard maps in matplotlib.cm.
  2. Create a mapping from time value to a color value recognized by matplotlib.pyplot.plot().

At the moment you're essentially doing both of these through the red and blue variables, which is fine for plt.plot(), but plt.colorbar() will require this information as a Matplotlib mappable object, e.g., a ScalarMappable. If you set up this object before you start plotting you can also use it to select the appropriate color in the plt.plot() call.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcol
import matplotlib.cm as cm

start_time = 100
end_time = 120

# Generate some dummy data.
tim = range(start_time,end_time+1)
xdat = np.arange(0,90.1)
ydat = [np.sin(0.2*(xdat-t)/np.pi) for t in tim]


# Make a user-defined colormap.
cm1 = mcol.LinearSegmentedColormap.from_list("MyCmapName",["r","b"])

# Make a normalizer that will map the time values from
# [start_time,end_time+1] -> [0,1].
cnorm = mcol.Normalize(vmin=min(tim),vmax=max(tim))

# Turn these into an object that can be used to map time values to colors and
# can be passed to plt.colorbar().
cpick = cm.ScalarMappable(norm=cnorm,cmap=cm1)
cpick.set_array([])



F = plt.figure()
A = F.add_subplot(111)
for y, t in zip(ydat,tim):
    A.plot(xdat,y,color=cpick.to_rgba(t))

plt.colorbar(cpick,label="Time (seconds)")

enter image description here

Deditos
  • 1,385
  • 1
  • 13
  • 23
  • When I run what you have above Python claims that `label` is not a keyword argument for `plt.colorbar()`. If I remove the label portion though everything runs just fine. – NeutronStar Sep 23 '14 at 16:54
  • Looks like `label` was added in Matplotlib v1.3.0 (May 2013), so that particular bit won't work with an earlier version. – Deditos Sep 23 '14 at 20:10