我有一个 2d numpy 数组 txtStrs
,其中包含我使用例如将其作为文本写入 matplotlib 图形轴 ax
的字符串
ax.text( posX, posY, txtStrs[0,0] )
稍后,我想更新这些文本(相同的位置、颜色等),而不重新绘制整个图形。因此,我将文本对象保存到另一个 numpy 数组中。
当我现在想要更新文本时,我使用了两个 for 循环
import numpy as np
import matplotlib.pyplot as plt
siz = 20
txtStrs = np.empty( (siz, siz), dtype = str )
txtObjs = np.empty( (siz, siz), dtype = object )
plt.figure()
ax = plt.gca()
for x in range(siz):
for y in range(siz)):
txtObjs[x,y] = ax.text( x, y, "" )
#Fill txtStrs with some string values
for x in range(siz):
for y in range(siz)):
txtObjs[x,y].set_text( txtStrs[x,y] )
最后一个 for 循环对我来说似乎是不必要的,而且并不是真正的 Python 风格。如果我不需要调用 set_text
方法,我可以使用 numpy 的内在推导式进行更新。
我的问题是:是否有其他方法将 txtStrs
传递给 txtObjs
,例如使用向量化、列表理解或其他什么?
最佳答案
循环是Pythonic的!
使用matplotlib.text
对象的set_text
方法也是有效的Python。这就是我们处理对象的方式——使用它们的方法。
使用numpy
,我们尝试避免循环,但只有当数组包含数字(或字符串)数据类型时,这才可以节省大量时间。然后它可以使用提供的数组方法在编译的代码中进行迭代。您的 txtObjs 数组是对象数据类型,并且此类数组上的大多数操作都涉及 Python 级别的迭代,即使它是隐藏的。与列表一样,对象数组包含指向内存中其他位置的对象的指针。它必须引用每个对象并使用自己的方法。
对象数组上的迭代比列表上的迭代慢一点,尽管数组的多维性质可以使迭代更漂亮。
列表理解是编写 for 循环的一种巧妙方法 - 如果您要返回一个新列表。它不适用于就地修改。对于一些“向量化”(隐藏)迭代的 numpy 函数也是如此。
如果 txtObjs
和 txtStrs
是相同大小的列表,则
for a, b in zip(txtObjs, txtStrs):
a.set_text(b)
应该更新所有text
对象。
对于二维数组:
for a, b in zip(txtObjs.ravel(), txtStrs.ravel()):
应该也可以工作。这些数组的二维形状妨碍了简单地传输值,尽管设置初始坐标可能很方便。
关于python - 如何以Python方式将numpy.array传递给numpy.array中对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55358808/