python - 每次运行后matplotlib标记类型顺序不一致?
问题描述
在不更改任何代码的情况下,绘制的图形将有所不同。在新的 bash 中第一次运行时纠正,在接下来的运行中混乱。(也许它可以循环回到正确的顺序)
具体来说:环境:MacOS Mojave 10.14.2,通过自制软件安装的python3.7.1。
要做的事情:scatter
在相同的 上绘制两到三组数据axes
,每组具有不同的markertype
和不同的colors
。绘制自定义图例,显示每个markertype
代表的数据集。
很抱歉,我没有足够的时间来准备可测试的代码(暂时),但这部分似乎是问题所在:
markerTypes = cycle(['o', 's', '^', 'd', 'p', 'P', '*'])
strainLegends = []
strains = list(set([idx.split('_')[0] for idx in pca2Plot.index]))
for strain in strains:
# markerType is fixed here, and shouldn't be passed on to the next python run anyway.
markerType = next(markerTypes)
# strainSamples connects directly to strain variable, then data is generated from getting strainSamples:
strainSamples = [sample for sample in samples if
sample.split('_')[0] == strain]
xData = pca2Plot.loc[strainSamples, 'PC1']
yData = pca2Plot.loc[strainSamples, 'PC2']
# See pictures below, data is correctly identified from source
# both scatter and legend instance use the same fixed markerType
ax.scatter(xData, yData, c=drawColors[strainSamples],
s=40, marker=markerType, zorder=3)
strainLegends.append(Line2D([0], [0], marker=markerType, color='k',
markersize=10,
linewidth=0, label=strain))
# print([i for i in ax.get_children() if isinstance(i, PathCollection)])
ax.legend(handles=strainLegends)
如您所见,数据markerType
与strain
数据相关。
对于第一次用python3 my_code.py
in bash 运行,它会创建一个正确的图片:看到圆形代表 A,方形代表 B
A = 圆形,B = 方形。看周围的正方形(-3, -3.8)
,这个数据点来自数据集 B。
如果我在同一个终端中再次运行代码,python3 my_code.py
请注意 A 和 B 完全聚集在一起,不相关。现在作为图例:A = 正方形,B = 圆形。再次查看(-3, -3.8)
来自数据集 B 的数据点,现在注释为 A。
如果我再次运行代码,它可能会产生另一个结果。
这是我用来生成注释的代码:
dictColor = {ax: pd.Series(index=pca2Plot.index), }
HoverClick = interactionHoverClick(
dictColor, fig, ax)
fig.canvas.mpl_connect("motion_notify_event", HoverClick.hover)
fig.canvas.mpl_connect("button_press_event", HoverClick.click)
在课堂HoverClick
上,我有
def hover(self, event):
if event.inaxes != None:
ax = event.inaxes
annot = self.annotAxs[ax]
# class matplotlib.collections.PathCollection, here refere to the scatter plotting event (correct?)
drawingNum = sum(isinstance(i, PathCollection)
for i in ax.get_children())
# print([i for i in ax.get_children() if isinstance(i, PathCollection)])
plotSeq = 0
jump = []
indInd = []
indIndInstances = []
for i in range(drawingNum):
sc = ax.get_children()[i]
cont, ind = sc.contains(event)
jump.append(len(sc.get_facecolor()))
indIndInstances.append(ind['ind'])
if cont:
plotSeq = i
indInd.extend(ind['ind'])
# here plotSeq is the index of last PathCollection instance that program find my mouse hovering on a datapoint of it.
sc = ax.get_children()[plotSeq]
cont, ind = sc.contains(event)
if cont:
try:
exist = (indInd[0] in self.hovered)
except:
exist = False
if not exist:
hovered = indInd[0]
pos = sc.get_offsets()[indInd[0]]
textList = []
for num in range(plotSeq + 1):
singleJump = sum(jump[:num])
textList.extend([self.colorDict[ax].index[i + singleJump]
for i in indIndInstances[num]])
text = '\n'.join(textList)
annot.xy = pos
annot.set_text(text)
annot.set_visible(True)
self.fig.canvas.draw_idle()
else:
if annot.get_visible():
annot.set_visible(False)
self.fig.canvas.draw_idle()
# hover
请注意,我注释了打印每个实例的代码。这是经过测试的,因为我认为它可能是在代码的其他部分中更改的实例顺序。但结果显示,无论对错,顺序都没有改变。
有谁知道发生了什么?以前有人经历过吗?如果我需要在代码末尾清理内存,我该怎么办?
解决方案
由于您的代码不完整,因此很难确定,但似乎标记的顺序被cycle
迭代器弄乱了。你为什么不试试:
markerTypes = ['o', 's', '^']
strainLegends = []
for strain, markerType in zip(strains, markerTypes):
strainSamples = [sample for sample in samples if sample.split('_')[0] == strain]
xData = pca2Plot.loc[strainSamples, 'PC1']
yData = pca2Plot.loc[strainSamples, 'PC2']
ax.scatter(xData, yData, c=drawColors[strainSamples], s=40, marker=markerType, zorder=3)
strainLegends.append(Line2D([0], [0], marker=markerType, color='k',
markersize=10,
linewidth=0, label=strain))
ax.legend(handles=strainLegends)
这当然假设strains
和markerTypes
具有相同的长度,并且标记在列表中的位置与您要分配的应变值相同。
推荐阅读
- python - 使用 oauth2client.service_account 和 google.oauth2 使用私钥签名之间的区别
- javascript - 单击注入 li 时显示警报
- node.js - google gcp nodejs 应用引擎随机关闭并自行重启
- reactjs - 使用反应打印的多页打印格式在第二页的页脚和页眉中重叠内容
- ios - UIScreen 亮度上的 Swift 选择器在调用时返回 UIDevice
- c# - 如何通过统一针对 Visual Studio 中错误的 .NET 框架来消除此错误警告
- javascript - 默认情况下如何以全屏模式启动 uwp webview 应用程序
- c - 僵尸进程去哪了?
- swift - 是否有任何方法或第三方支持在可可应用程序中将 CSV 文件快速转换为 PDF?
- swift - 用户 KILL 应用程序时如何关闭所有呈现的视图控制器?