Convert ax.scatter to ax.plot: get error: ValueError: range(0, 5000) is not a valid value for color

Working through Python Crash Course 3ed. Stuck on exercise 15-3 Molecular Motion.

I took the code from rw_visual.py, and replaced 3 occurrences of “ax.scatter” with “ax.plot”. The program died. The error is:

ValueError: range(0, 5000) is not a valid value for color

File “exercise_15_3.py”, line 20, in
ax.plot(rw.x_values, rw.y_values, c=point_numbers,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If I change “ax.plot” back to “ax.scatter”, it works great.

It looks like it has to do with color mapping.

  1. If the color range(0,5000) is not valid for the “ax.plot” graph type, why does it work on the “ax.scatter” graph type?
  2. How do you make it work with ax.plot?

Code below:

import matplotlib.pyplot as plt
from random_walk import RandomWalk

# Keep making new walks, as long as the program is active.
while True:

    rw = RandomWalk(5_000)
    rw.fill_walk()

    # Plot the points in the walk.
    plt.style.use('classic')
    #fig, ax = plt.subplots()
    #fig, ax = plt.subplots(figsize=(15, 9))
    fig, ax = plt.subplots(figsize=(10, 6), dpi=128)

    point_numbers = range(rw.num_points)
    print(type(point_numbers))
    #ax.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
    #    edgecolors='none', s=15)

    ax.plot(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
        edgecolors='none', s=1)

    ax.set_aspect('equal')

     # Emphasize the first and last points.
    ax.plot(0, 0, c='green', edgecolors='none', s=100)
    ax.plot(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none',
        s=100)

    # Remove the axes.
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    plt.show()

The c parameter in ax.scatter accepts an array-like or list of marker colors. So c=point_numbers is assigning a color to each point in the scatter plot. ax.scatter documentation

Line plots typically assign one color to a line so c is expected to be a single color. There are other differences between the parameters for ax.scatter and ax.plot such as s for size in a scatter plot changes to ms for the marker size in a line plot and edgecolors in ax.scatter corresponds to markeredgecolor for line plots. ax.plot documentation

This may make the kind of plot you want using ax.plot

import matplotlib.pyplot as plt
from random_walk import RandomWalk

rw = RandomWalk(5_000)
rw.fill_walk()

# Plot the points in the walk.
fig, ax = plt.subplots(figsize=(10, 6), dpi=128)

point_numbers = range(rw.num_points)
# ax.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
#            edgecolors='none', s=15)

ax.plot(rw.x_values, rw.y_values, c='gray', 
        markeredgecolor='none', marker='.', markersize=4, 
        linewidth=1)

ax.set_aspect('equal')

# Emphasize the first and last points.
# Line plots need two points to plot a line, so use ax.scatter
# to plot the beginning and end points.  Set zorder > 1
# to move the endpoints above the plotted lines
ax.scatter((0, rw.x_values[-1]), (0, rw.y_values[-1]), c=['green', 'red'], 
           edgecolors='none', s=100, zorder=5)


# Remove the axes.
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

plt.show()

Hi, Scott.

Sorry for the delay in responding. Thank you for the help!. You solution works great! When I read what you wrote, I thought to myself “Doh!” Thank you for being willing to help newbies.

Jeff Kayser