Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Line colour of 3D parametric curve in python's matplotlib.pyplot

Tags:

I've been googling quite some time with no success ... maybe my keywords are just lousy. Anyway, suppose I have three 1D numpy.ndarrays of the same length I'd like to plot them in 3D as a trajectory. Moreover, I'd like to be able to do either of the following things:

  1. Change the colour of the line as a function of z
  2. Change the colour of the line as a function of time (i.e. the index in the arrays)

This demo has an example of making such a curve:

import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D import numpy as np import matplotlib.pyplot as plt  fig = plt.figure() ax = fig.gca(projection='3d') theta = np.linspace(-4 * np.pi, 4 * np.pi, 100) z = np.linspace(-2, 2, 100) r = z**2 + 1 x = r * np.sin(theta) y = r * np.cos(theta) ax.plot(x, y, z)  plt.show() 

enter image description here

But how do I achieve 1 or 2? Solutions to only one or the other are welcome! Thanks in advance.

like image 500
Ian Hincks Avatar asked Mar 25 '13 14:03

Ian Hincks


People also ask

How do I change the color of a line in matplotlib?

The usual way to set the line color in matplotlib is to specify it in the plot command. This can either be done by a string after the data, e.g. "r-" for a red line, or by explicitely stating the color argument.

Can matplotlib Pyplot be used to display 3D plots?

In order to plot 3D figures use matplotlib, we need to import the mplot3d toolkit, which adds the simple 3D plotting capabilities to matplotlib. Once we imported the mplot3d toolkit, we could create 3D axes and add data to the axes.


2 Answers

As with normal 2d plots, you cannot have a gradient of color along an ordinary line. However, you can do it with scatter:

import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D import numpy as np import matplotlib.pyplot as plt  fig = plt.figure() ax = fig.gca(projection='3d') theta = np.linspace(-4 * np.pi, 4 * np.pi, 100) z = np.linspace(-2, 2, 100) r = z**2 + 1 x = r * np.sin(theta) y = r * np.cos(theta)  #1 colored by value of `z` ax.scatter(x, y, z, c = plt.cm.jet(z/max(z)))   #2 colored by index (same in this example since z is a linspace too) N = len(z) ax.scatter(x, y, z, c = plt.cm.jet(np.linspace(0,1,N)))  plt.show() 

I liked @Junuxx's hack so I applied it here:

for i in xrange(N-1):     ax.plot(x[i:i+2], y[i:i+2], z[i:i+2], color=plt.cm.jet(255*i/N)) 

2-Color by index2-Color lines by index

like image 104
askewchan Avatar answered Sep 20 '22 11:09

askewchan


You can plot every line segment separately, as shown below. This just loops over 6 predefined colors, since @askewchan's answer already demonstrates well how to use a colormap.

cols = 'rgbcmy'  for i in range(len(x)-1):     ax.plot(x[i:i+2], y[i:i+2], z[i:i+2], color=cols[i%6]) 

enter image description here

like image 45
Junuxx Avatar answered Sep 20 '22 11:09

Junuxx