点击子图中选定数据点更改颜色

3

您好,Stack-Overflow:

我是一个相对初学者,并且在以下任务上卡住了:我想通过单击数据点本身来更改数据点的颜色。我创建了随机子图,但只能在最后一个子图中更改点的颜色(单击其他位置也只会在最后一个子图中更改颜色)。我错过了什么吗?

import numpy as np
import matplotlib.pyplot as plt
import random
import sys


fig, axes = plt.subplots(nrows=5, ncols=3, sharex=True, sharey=True)
xlim = (0, 30)
ylim = (0, 15)
plt.xticks(np.arange(0, 15, 5))
plt.yticks(np.arange(0, 15, 5))
plt.xticks(np.arange(0, 30, 5))
plt.setp(axes, xlim=xlim, ylim=ylim)

for i in range(0, 5, 1):
    for j in range(0, 3, 1):
        X_t = np.random.rand(10, 4) * 20
        points = axes[i][j].scatter(X_t[:, 0], X_t[:, 1],
                                    facecolors=["C0"] * len(X_t), edgecolors=["C0"] * len(X_t), picker=True)


def onpick(event):
    print(X_t[event.ind], "clicked")
    points._facecolors[event.ind, :] = (1, 1, 0, 1)
    points._edgecolors[event.ind, :] = (1, 0, 0, 1)
    fig.canvas.draw()


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


plt.show()

似乎事件.ind中包含的信息不正确,我在错误的时刻请求了那些信息。

我会感激任何帮助!

问候!

(对建议的最佳实践进行编辑)


“points” 在每次迭代中都被覆盖。你只能在最后一个子图上操作并不是什么意外。 - gboffi
嗨@gboffi!是的,我明白在points中的点总是最后一个值。但是我如何访问该特定子图中点的信息? - Amadeus
我不知道如何完全解决你的问题,我只是想强调可能存在的误解(因此是评论而不是答案 :-))。 - gboffi
1个回答

1
你需要保存所有子图的点,并通过event.artist检查当前点击的子图(参考这个问题
import numpy as np
import matplotlib.pyplot as plt


fig, axes = plt.subplots(nrows=5, ncols=3, sharex=True, sharey=True)
xlim = (0, 30)
ylim = (0, 15)
plt.xticks(np.arange(0, 15, 5))
plt.yticks(np.arange(0, 15, 5))
plt.xticks(np.arange(0, 30, 5))
plt.setp(axes, xlim=xlim, ylim=ylim)

points_list = []   ###
for i in range(0, 5, 1):
    for j in range(0, 3, 1):
        X_t = np.random.rand(10, 4) * 20
        points_list.append(axes[i][j].scatter(X_t[:, 0], X_t[:, 1],
                                              facecolors=["C0"] * len(X_t), edgecolors=["C0"] * len(X_t), picker=True))   ###


def onpick(event):
    print(event.artist, X_t[event.ind], "clicked")
    for points in points_list:
        if event.artist == points:  ###
            points._facecolors[event.ind, :] = (1, 1, 0, 1)
            points._edgecolors[event.ind, :] = (1, 0, 0, 1)

    fig.canvas.draw()


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

从检查 event.artist == points 可以看出,你可以直接使用 event.artist 而不是将所有点保存在列表中:
def onpick(event):
    print(event.artist, X_t[event.ind], "clicked")
    event.artist._facecolors[event.ind, :] = (1, 1, 0, 1)
    event.artist._edgecolors[event.ind, :] = (1, 0, 0, 1)
    fig.canvas.draw()

谢谢!列表运行得很完美。我试图将每个点计算到字典中,但您的解决方案更加优雅。 - Amadeus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接