gpt4 book ai didi

python - 如何在子图中选择一个点并在 matplotlib 的相邻子图中突出显示它(点区域的扩展)

转载 作者:太空宇宙 更新时间:2023-11-04 01:19:11 26 4
gpt4 key购买 nike

我想创建一个由一些子图组成的散点图矩阵。我从 .txt 文件中提取了我的数据并创建了一个形状数组 (x,y,z,p1,p2,p3)。数组的前三列表示这些数据来自原始图像的 x、y、z 坐标,最后三列(p1、p2、p3)表示一些其他参数。因此,在数组的每一行中,参数 p1、p2、p3 具有相同的坐标(x、y、z)。在散点图中,我想在第一阶段根据 p2、p3 参数可视化 p1 参数。对于我选择的每个点,我希望对数组前三列中的 (x,y,z) 参数进行注释,并突出显示相邻子图中具有相同坐标的点或修改其颜色。

在我的代码中,创建了两个子图,并在终端中打印了通过选取一个点获得的 (p1,p2 或 p3) 值,相邻子图中同一点的相应值以及 (x, y,z)该点的参数。

此外,当我在第一个子图中选择一个点时,第二个子图中对应点的颜色会发生变化,但反之亦然。这种颜色修改只有在我手动调整图形大小时才能识别。我怎样才能为两个子图添加交互性,而不必调整图形以注意到任何变化?我应该进行什么样的修改才能使这种交互性在像这个问题“Is there a function to make scatterplot matrices in matplotlib?”中那样的减少的散点图矩阵中可行。我不是经验丰富的 python、matplotlib 用户,因此我们将不胜感激

import numpy as np
import matplotlib.pyplot as plt
import pylab as pl



def main():


#load data from file
data = np.loadtxt(r"data.txt")

plt.close("all")
x = data[:, 3]
y = data[:, 4]
y1 = data[:, 5]
fig1 = plt.figure(1)
#subplot p1 vs p2
plt.subplot(121)
subplot1, = plt.plot(x, y, 'bo', picker=3)
plt.xlabel('p1')
plt.ylabel('p2')

#subplot p1 vs p3
plt.subplot(122)
subplot2, = plt.plot(x, y1, 'bo', picker=3)
plt.xlabel('p1')
plt.ylabel('p3')

plt.subplots_adjust(left=0.1, right=0.95, wspace=0.3, hspace=0.45)
# art.getp(fig1.patch)
def onpick(event):

thisevent = event.artist
valx = thisevent.get_xdata()
valy = thisevent.get_ydata()
ind = event.ind

print 'index', ind
print 'selected point:', zip(valx[ind], valy[ind])
print 'point in the adjacent subplot', x[ind], y1[ind]
print '(x,y,z):', data[:, 0][ind], data[:, 1][ind], data[:, 2][ind]

for xcord,ycord in zip(valx[ind], valy[ind]):
plt.annotate("(x,y,z):", xy = (x[ind], y1[ind]), xycoords = ('data' ),
xytext=(x[ind] - .5, y1[ind]- .5), textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"),
)
subplot2, = plt.plot(x[ind], y[ind], 'ro', picker=3)
subplot1 = plt.plot(x[ind], y[ind], 'ro', picker=3)


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

plt.show()



main()

Results

总而言之,当我选择一个点时,信息会独立于子图打印在终端中。但是,当我在左侧子图中选择一个点时,颜色仅在右侧子图中的点中被修改,反之亦然。此外,直到我调整图形(例如移动它或调整它的大小)并且当我选择第二个点时,前一个点仍然是彩色的,否则颜色的变化是不明显的。

任何类型的贡献都将受到赞赏。提前谢谢你。

最佳答案

您的当前代码已经在正确的轨道上。您基本上只是在 onpick 函数中错过了对 plt.draw() 的调用。

但是,在我们的评论讨论中,mpldatacursor 出现了,您问了一个以这种方式做事的例子。

mpldatacursor 中的当前 HighlightingDataCursor 是围绕突出显示整个 Line2D 艺术家的想法而设置的,而不仅仅是它的特定索引。 (它故意有点限制,因为在 matplotlib 中没有为任何艺术家绘制任意高光的好方法,所以我将高光部分保持得很小。)

但是,您可以将与此类似的东西子类化(假设您正在使用 plot 并希望使用您在每个轴上绘制的第一个东西)。我还说明了如何使用 point_labels,以防您想为显示的每个点设置不同的标签。

import numpy as np
import matplotlib.pyplot as plt
from mpldatacursor import HighlightingDataCursor, DataCursor

def main():
fig, axes = plt.subplots(nrows=2, ncols=2)
for ax, marker in zip(axes.flat, ['o', '^', 's', '*']):
x, y = np.random.random((2,20))
ax.plot(x, y, ls='', marker=marker)
IndexedHighlight(axes.flat, point_labels=[str(i) for i in range(20)])
plt.show()

class IndexedHighlight(HighlightingDataCursor):
def __init__(self, axes, **kwargs):
# Use the first plotted Line2D in each axes
artists = [ax.lines[0] for ax in axes]

kwargs['display'] = 'single'
HighlightingDataCursor.__init__(self, artists, **kwargs)
self.highlights = [self.create_highlight(artist) for artist in artists]
plt.setp(self.highlights, visible=False)

def update(self, event, annotation):
# Hide all other annotations
plt.setp(self.highlights, visible=False)

# Highlight everything with the same index.
artist, ind = event.artist, event.ind
for original, highlight in zip(self.artists, self.highlights):
x, y = original.get_data()
highlight.set(visible=True, xdata=x[ind], ydata=y[ind])
DataCursor.update(self, event, annotation)

main()

enter image description here

同样,这假设您使用的是 plot 而不是 scatter。使用 scatter 可以做到这一点,但您需要更改大量令人讨厌的细节。 (没有通用的方法来突出显示任意 matplotlib 艺术家,因此您必须有很多非常冗长的代码来单独处理每种类型的艺术家。)

无论如何,希望它有用。

关于python - 如何在子图中选择一个点并在 matplotlib 的相邻子图中突出显示它(点区域的扩展),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22355435/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com