我仍然堅信使用單散點圖將是更好的選擇。這個問題中沒有任何東西會與此相矛盾。
您可以將所有數據合併到一個DataFrame中,並將其列爲group, id, x, y, color
。在下面它說「創造一些數據集」的代碼部分不建立這樣一個數據幀
group id x y color
0 1 AEBB 0 0 palegreen
1 3 DCEB 1 0 plum
2 0 EBCC 2 0 sandybrown
3 0 BEBE 3 0 sandybrown
4 3 BEBB 4 0 plum
注意,每個組都有自己的顏色。然後可以使用color
列中的顏色從中創建散點圖。
在this previous question中註冊挑選事件,並且一旦點擊了一個不是黑色的點,就獲得與所選點對應的DataFrame中的id
。從id中,通過「黑匣子函數」生成其他id,並且對於通過這種方式獲得的每個id,確定數據幀中的點的相應索引。因爲我們有單散點,所以這個索引直接是分散點(PathCollection
)中點的索引,我們可以將它繪成黑色。
import numpy as np; np.random.seed(1)
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors
### create some dataset
x,y = np.meshgrid(np.arange(20), np.arange(20))
group = np.random.randint(0,4,size=20*20)
l = np.array(np.meshgrid(list("ABCDE"),list("ABCDE"),
list("ABCDE"),list("ABCDE"))).T.reshape(-1,4)
ide = np.random.choice(list(map("".join, l)), size=20*20, replace=False)
df = pd.DataFrame({"id" : ide, "group" : group ,
"x" : x.flatten(), "y" : y.flatten() })
colors = ["sandybrown", "palegreen", "paleturquoise", "plum"]
df["color"] = df["group"]
df["color"].update(df["color"].map(dict(zip(range(4), colors))))
print df.head()
### plot a single scatter plot from the table above
fig, ax = plt.subplots()
scatter = ax.scatter(df.x,df.y, facecolors=df.color, s=64, picker=4)
def getOtherIDsfromID(ID):
""" blackbox function: create a list of other IDs from one ID """
l = [np.random.permutation(list(ID)) for i in range(5)]
return list(set(map("".join, l)))
def select_point(event):
if event.mouseevent.button == 1:
facecolor = scatter._facecolors[event.ind,:]
if (facecolor == np.array([[0, 0, 0, 1]])).all():
c = df.color.values[event.ind][0]
c = matplotlib.colors.to_rgba(c)
scatter._facecolors[event.ind,:] = c
else:
ID = df.id.values[event.ind][0]
oIDs = getOtherIDsfromID(ID)
# for each ID obtained, make the respective point black.
rows = df.loc[df.id.isin([ID] + oIDs)]
for i, row in rows.iterrows():
scatter._facecolors[i,:] = (0, 0, 0, 1)
tx = "You selected id {}.\n".format(ID)
tx += "Points with other ids {} will be affected as well"
tx = tx.format(oIDs)
print tx
fig.canvas.draw_idle()
fig.canvas.mpl_connect('pick_event', select_point)
plt.show()
在下面的圖像,與ID DAEE
點已經被點擊,並且其它點與IDS [「EDEA」,「DEEA」,「EDAE」,「DEAE」]已經由黑盒選擇功能。並非所有這些ID都存在,因此其他兩個帶有現有ID的點也會着色。
![enter image description here](https://i.stack.imgur.com/Z4HKD.png)
有matplotlib的onclick事件:https://matplotlib.org/users/event_handling.html – Moritz