Matplotlib绘图生成器

5

当我在Python3中执行以下命令时,它会生成一个图表:

import matplotlib.pyplot as plt

a = [1,2,3,4,5]

plt.plot(range(5), a)
plt.show()

据我所知,在Python 3中,range()返回一个迭代器,因此我的代码基本上是在迭代器上绘图。现在我的问题是,为什么我不能这样做:
def myGen(iterable):
    for i in iterable:
        yield i
a = myGen([1,2,3,4,5])
plt.plot(range(5),a)
plt.show()

当我尝试时,出现ValueError: x 和 y 必须具有相同的第一维

仔细想一想,希望在两个生成器上绘制图形是很有意义的。只需逐点绘制即可。这在matplotlib中是否可行?

我知道有一个类似的帖子,但不幸的是没有答案。


1
range不是一个迭代器,它是一个不可变序列plt.plot(range(5), (i for i in (1,2,3,4,5)))会以同样的方式失败,你不能将生成器传递给plot。 - Padraic Cunningham
@PadraicCunningham:那与此无关。它会失败,不是因为range,而是因为生成器表达式。 - BrenBarn
@BrenBarn,那正是我刚才所说的。 - Padraic Cunningham
@PadraicCunningham:但这正是他所问的:为什么他不能将生成器传递给plot函数? - BrenBarn
@BrenBarn,不是因为range起作用而生成器失败,OP认为它们是可比较的,但实际上它们是不可比较的。 - Padraic Cunningham
显示剩余4条评论
1个回答

4
事实上,即使在Python 3中,range不是一个真正的列表,它仍然提供比您自定义的生成器更多的功能。特别是,它提供了__len__。这非常重要,因为matplotlib在幕后将所有内容转换为numpy数组,而numpy数组需要事先知道其大小。Python 3的range对象还提供了项目访问,因此它们确实非常像普通序列。您可以在文档中看到它们不是简单的生成器。
我不确定您需要做哪些工作才能使自己的自定义类在这里起作用,但这可能不值得麻烦。Matplotlib需要能够将您的数据转换为numpy数组,而numpy反过来需要比简单的“此对象可迭代”更多的信息。它需要能够知道有多少数据并一次性获取所有数据。

如果matplotlib可以将我放在参数中的任何适当内容转换为numpy数组,那么我宁愿一开始就传入一个numpy数组。我希望matplotlib有一个算法,可以接受两个生成器并对它们进行某种__next __()调用,并重复绘制图形点,然后当我在图形上调用show()时,它只是呈现并以某种方式获取所有绘制在图形上的点。但是,显然我只会传递数组。 - Deniz
@Deniz:不,它不会这样做。就像我说的那样,它会在开始时将整个数据集转换为numpy数组。 - BrenBarn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接