Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an array of y-values that form a line. Additionally, I have an array with the same number of elements as the y-array of values ranging from 0 to 1. We'll call this array 'z'. I want to plot the array of y-values so that the color of each point corresponds with the z-value.

In gnuplot, you can do this using the 'lc variable':

plot ’data’ using 1:2:3 with points lc variable  

Using the advice from here: Matplotlib scatterplot; colour as a function of a third variable , I was able to use a scatter plot, which did work:

import matplotlib as mpl  
import matplotlib.pyplot as plt  

plt.scatter(x, y, c=z, s=1, edgecolors='none', cmap=mpl.cm.jet)  
plt.colorbar()  
plt.show()  

Is there a way to do this with the plot method in matplotlib, similar to this?

plt.plot(x, y, c=z)

When I tried the above code, all of the lines just appeared black.

share|improve this question
add comment

2 Answers

up vote 2 down vote accepted

you can use scatter:

plt.scatter(range(len(y)), y, c=z, cmap=cm.hot)

here you have the ipython -pylab session:

In [27]: z = [0.3,0.4,0.5,0.6,0.7,0.2,0.3,0.4,0.5,0.8,0.9]

In [28]: y = [3, 7, 5, 6, 4, 8, 3, 4, 5, 2, 9]

In [29]: plt.scatter(range(len(y)), y, s=60, c=z, cmap=cm.hot)
Out[29]: <matplotlib.collections.PathCollection at 0x9ec8400>

If you want to use plot you can get the equivalent figure as above with (pycrust session):

>>> from matplotlib import pyplot as plt
>>> from matplotlib import cm
>>> y = [3,7,5,6,4,8,3,4,5,2,9]
>>> z = [0.3,0.4,0.5,0.6,0.7,0.2,0.3,0.4,0.5,0.8,0.9]
>>> for x, (v, c) in enumerate(zip(y,z)):
...      plt.plot(x,v,marker='o', color=cm.hot(c))
...      
[<matplotlib.lines.Line2D object at 0x0000000008C42518>]
[<matplotlib.lines.Line2D object at 0x0000000008C426D8>]
[<matplotlib.lines.Line2D object at 0x0000000008C42B38>]
[<matplotlib.lines.Line2D object at 0x0000000008C452B0>]
[<matplotlib.lines.Line2D object at 0x0000000008C45438>]
[<matplotlib.lines.Line2D object at 0x0000000008C45898>]
[<matplotlib.lines.Line2D object at 0x0000000008C45CF8>]
[<matplotlib.lines.Line2D object at 0x0000000008C48198>]
[<matplotlib.lines.Line2D object at 0x0000000008C485F8>]
[<matplotlib.lines.Line2D object at 0x0000000008C48A58>]
[<matplotlib.lines.Line2D object at 0x0000000008C4B1D0>]
>>> plt.show()
>>> 
share|improve this answer
add comment

I had the same problem: wanted to plot line(s) with non-uniform color, which I wanted to be dependent on a third variable (z).

But I definitelly wanted to use a line, not markers (as in @joaquin's answer). I found a solution in a matplotlib gallery example, using the class matplotlib.collections.LineCollection (link here).

Here is my example, which plots trajectories in a Basemap, coloring them according to its height:

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.collections import LineCollection
import numpy as np

m = Basemap(llcrnrlon=-42,llcrnrlat=0,urcrnrlon=5,urcrnrlat=50, resolution='h')
fig = plt.figure()
m.drawcoastlines()
m.drawcountries()

for i in trajectorias:
    # for each i, the x (longitude), y (latitude) and z (height)
    # are read from a file and stored as numpy arrays

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

    lc = LineCollection(segments, cmap=plt.get_cmap('Spectral'),
                        norm=plt.Normalize(250, 1500))
    lc.set_array(z)
    lc.set_linewidth(2)

    plt.gca().add_collection(lc)

axcb = fig.colorbar(lc)
axcb.set_label('cota (m)')

plt.show()

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.
{"cc_re__cc_re__cc_by_sa_3_0": ["        <li><a href=\"http://area51.stackexchange.com\" title=\"proposing new sites in the Stack Exchange network\">Area 51</a></li>\r\n                        <li><a href=\"http://careers.stackoverflow.com\">Stack Overflow Careers</a></li>\r\n                    \r\n                </ol>\r\n            </td>\r\n    </tr>\r\n</table>\r\n                </div>\r\n            </div>\r\n\r\n            <div id=\"copyright\">\r\n                site design / logo &#169; 2014 stack exchange inc; user contributions licensed under <a href=\"http://creativecommons.org/licenses/by-sa/3.0/\" rel=\"license\">cc by-sa 3.0</a> \r\n                with <a href=\"http://blog.stackoverflow.com/2009/06/attribution-required/\" rel=\"license\">attribution required</a>\r\n            </div>\r\n            <div id=\"svnrev\">\r\n                rev 2014.4.18.1558\r\n            </div>\r\n            \r\n        </div>\r\n    </div>\r\n    <noscript>\r\n        <div id=\"noscript-warning\">Stack Overflow works best with JavaScript enabled<img src=\"http://pixel.quantserve.com/pixel/p-c1rF4kxgLUzNc.gif\" alt=\"\" class=\"dno\"></div>\r\n    </nos"], "copyright__copyright__copyright": ["=1)\n\n    lc = LineCollection(segments, cmap=plt.get_cmap('Spectral'),\n                        norm=plt.Normalize(250, 1500))\n    lc.set_array(z)\n    lc.set_linewidth(2)\n\n    plt.gca().add_collection(lc)\n\naxcb = fig.colorbar(lc)\naxcb.set_label('cota (m)')\n\nplt.show()\n\nshare|improve this answer\nadd comment\n\nYour Answer\n\n\u00a0\ndiscard\n\nBy posting your answer, you agree to the privacy policy and terms of service.\n\nNot the answer you're looking for? Browse other questions tagged or ask your own question."]}