简体   繁体   中英

Matplotlib: Change color of point in 3D scatter plot onpick

I am rendering a 3D scatter plot and want to change the color of the points to red when they are clicked. When a new point is clicked, I want the color of the previously-clicked points to go back to the default. So far, I cannot even get matplotlib to change the color of the point when clicked. Does anyone know what is wrong, or if this is not supported for 3D scatter plots?

points = ax1.scatter(X_t[:,0], X_t[:,1], X_t[:,2], picker=True)

def plot_curves(indexes):
    for i in indexes: # might be more than one point if ambiguous click
        points._facecolors[i,:] = (1, 0, 0, 1)
        points._edgecolors[i,:] = (1, 0, 0, 1)
    plt.draw()

def onpick(event):
    ind = event.ind
    plot_curves(list(ind))

fig.canvas.mpl_connect('pick_event', onpick)
plt.show()

The scatter only has a single color for all points. So you cannot change the 5th row of an array which only has a single row. So first you need to make sure the facecolors are all set individually via the facecolors argument. Then you can obtain them in an array format and once a click happens, supply a copy of the original array with the respective element changed to the scatter.

2D

import numpy as np
import matplotlib.pyplot as plt

X_t = np.random.rand(10,4)*20

fig, ax1 = plt.subplots()


points = ax1.scatter(X_t[:,0], X_t[:,1], 
                     facecolors=["C0"]*len(X_t), edgecolors=["C0"]*len(X_t), picker=True)
fc = points.get_facecolors()

def plot_curves(indexes):
    for i in indexes: # might be more than one point if ambiguous click
        new_fc = fc.copy()
        new_fc[i,:] = (1, 0, 0, 1)
        points.set_facecolors(new_fc)
        points.set_edgecolors(new_fc)
    fig.canvas.draw_idle()

def onpick(event):
    ind = event.ind
    plot_curves(list(ind))

fig.canvas.mpl_connect('pick_event', onpick)
plt.show()

3D

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

X_t = np.random.rand(10,4)*20

fig, ax1 = plt.subplots(subplot_kw=dict(projection="3d"))


points = ax1.scatter(X_t[:,0], X_t[:,1], X_t[:,2],
                     facecolors=["C5"]*len(X_t), edgecolors=["C5"]*len(X_t), picker=True)
fc = points.get_facecolors()

def plot_curves(indexes):
    for i in indexes: # might be more than one point if ambiguous click
        new_fc = fc.copy()
        new_fc[i,:] = (1, 0, 0, 1)
        points._facecolor3d = new_fc
        points._edgecolor3d = new_fc
    fig.canvas.draw_idle()

def onpick(event):
    ind = event.ind
    plot_curves(list(ind))

fig.canvas.mpl_connect('pick_event', onpick)
plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM