首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >冗余matplotlib.text.Text对象

冗余matplotlib.text.Text对象
EN

Stack Overflow用户
提问于 2022-02-18 08:41:55
回答 1查看 126关注 0票数 0

这个Python 3.8.10和matplotlib 3.5.1代码片段:

代码语言:javascript
复制
import matplotlib.pyplot as plt
import matplotlib.text as text

plt.axis('off')
print(plt.findobj(match=text.Text))
plt.show()

生成一个空的查看器窗口:

这张名单上有很多副本:

代码语言:javascript
复制
[Text(0.5, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0.5, ''), Text(0, 0.5, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0.5, 1.0, ''), Text(0.0, 1.0, ''), Text(1.0, 1.0, '')]

他们是什么?有必要吗?如何防止它们被创造出来?怎样才能摆脱他们?

我的目标是交互式地添加和删除文本标签。这些无法删除的初始文本对象的存在使其变得更加复杂。理想情况下,我希望有一个函数来删除所有的文本标签。我创建了一组基于鼠标单击坐标的上下文相关标签,并在下一次单击时删除并重新生成整个集合。

EN

回答 1

Stack Overflow用户

发布于 2022-02-18 10:20:06

创建这些文本对象是因为使用plt.axis("off"),您创建了一个具有标准x-/y-滴答和相应的滴答标签(即文本对象)的axis对象。对于matplotlib,我假设要设置一个不可见的轴,它必须存在,但是我还没有查看源代码来验证这一点。

代码语言:javascript
复制
import matplotlib.pyplot as plt
import matplotlib.text as text

text_before = plt.findobj(match=text.Text)
plt.axis('off')
text_after = plt.findobj(match=text.Text)

print("before ", text_before)
print("after ", text_after)

#plt.show()

输出:

代码语言:javascript
复制
before  []    
after  [Text(0.5, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0, ''), Text(0, 1, ''), Text(0, 0.5, ''), Text(0, 0.5, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0, 0, ''), Text(1, 0, ''), Text(0.5, 1.0, ''), Text(0.0, 1.0, ''), Text(1.0, 1.0, '')]

即使只是试图定位当前轴,也会生成以前不存在的图形和轴:

代码语言:javascript
复制
print("before", plt.get_fignums())
plt.gca()
print("after", plt.get_fignums())

输出:

代码语言:javascript
复制
before []
after [1]

我认为没有必要删除文本对象,因为它们不会影响最终图像的呈现,而且对于图像生成来说是相当惰性的。而且似乎也没有通过matplotlib实现删除轴上固有的文本艺术家,比如勾标和标题(以及表示脊柱和蜱的Line2D对象):

代码语言:javascript
复制
import matplotlib.pyplot as plt
import matplotlib.text as text

#the axis object itself can be removed
ax = plt.gca()
#the axis-inherent objects title and tick labels (and not tested here spine and tick Line2D objects)
#cannot be removed
ax_title = plt.title("This is the title") 
_, (ax_label, _, _) = plt.xticks(range(3), list("ABC"))
#text added by user can be removed
ax_text_visible = ax.annotate("This text is visible", (0.30, 0.20), xycoords="axes fraction")
ax_text_invisible = ax.annotate("This text is not visible", (0.20, 0.50), xycoords="axes fraction", visible=False)
ax_text_outside = ax.annotate("This text is outside the canvas", (20, 50), xycoords="axes fraction")
ax_text_not_annotation = plt.text(0.3, 0.7, "Not an annotation")
#test generated objects for existence of the remove method 
test_list = [ax, ax_title, ax_label, ax_text_visible, ax_text_invisible, ax_text_outside, ax_text_not_annotation]
#generate a list of user-created Text objects that ignores axis-inherent text objects
removable_objects = [item for item in test_list if item._remove_method]
for item in removable_objects:
    print(item, type(item))

输出:

代码语言:javascript
复制
AxesSubplot(0.125,0.11;0.775x0.77) <class 'matplotlib.axes._subplots.AxesSubplot'>
Annotation(0.3, 0.2, 'This text is visible') <class 'matplotlib.text.Annotation'>
Annotation(0.2, 0.5, 'This text is not visible') <class 'matplotlib.text.Annotation'>
Annotation(20, 50, 'This text is outside the canvas') <class 'matplotlib.text.Annotation'>
Text(0.3, 0.7, 'Not an annotation') <class 'matplotlib.text.Text'>

因此,我们可以使用remove()方法识别用户放置在轴上的所有文本(不包括标题和勾标):

代码语言:javascript
复制
#test that all removable user text is also found when screening with ax.findobj(match=text.Text)
matched_text = [item for item in ax.findobj(match=text.Text) if item._remove_method] 
print(set(matched_text) == set(removable_objects[1:])) 
>>>True
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71170568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档