2

I am trying to plot multiple lines in space (each of which connect a pair of points) on one 3D graph in Python using matplotlib, and I want each line to be colored differently based on how long it is (i.e., the longest line would be red, a middle-length line would be orange-ish, etc.).

I have all of the line lengths computed.

My points' coordinates are carried in separate arrays like so:

x1 = # all of the x coordinates of the primary points
y1 = # all of the y coordinates of the primary points
z1 = # all of the z coordinates of the primary points

x2 = # all of the x coordinates of the secondary points
y2 = # all of the y coordinates of the secondary points
z2 = # all of the z coordinates of the secondary points

where each line has endpoints (x1[i],y1[i],z1[i]) and (x2[i],y2[i],z2[i]) and i is the index of the line.

How might I use a heatmap or some other Python function to color each line accordingly? I think I understand how heatmaps can be used to plot a set of data, but I am trying to plot separate lines and color them based on some reference length (i.e., lenth_max, which would be the "hottest" length).

  • possible duplicate of [Using Colormaps to set color of line in matplotlib](http://stackoverflow.com/questions/8931268/using-colormaps-to-set-color-of-line-in-matplotlib) – farenorth Aug 12 '15 at 01:16

1 Answers1

3

Here's an example with some random length lines. The distance of the lines will have to be computed, and then normalised to the same range as a colormap. I picked 'hot', but you can pick any, the '_r' behind 'hot' reverses the colormap.

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.cm as mplcm
import matplotlib.colors as colors
import numpy as np
from random import randint

fig = plt.figure()
ax = Axes3D(fig)

num_lines = 50
lines, distances = [], []
for x in range(0, num_lines):
    xs = [0, randint(10, 150)]
    ys = [0, 5]
    zs = [0, randint(10,60)]
    lines.append([xs, ys, zs])

    distance = np.sqrt((xs[0]-xs[1])**2+(ys[0]-ys[1])**2+(zs[0]-zs[1])**2)  # calculate length of a line
    distances.append(distance)

distances_normalised = distances / (np.max(distances)/num_lines)  # normalise lengths of lines
cNorm = colors.Normalize(vmin=0, vmax=num_lines - 1)

cm = plt.get_cmap('hot_r')
scalarMap = mplcm.ScalarMappable(norm=cNorm, cmap=cm)

for dist, line in enumerate(lines):
    ax.plot(line[0], line[1], line[2], color=scalarMap.to_rgba(distances_normalised[dist]))

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

plt.show()

enter image description here

Chris
  • 1,287
  • 12
  • 31