Python 中的 Matplotlib - 绘制形状并为其设置动画

发布于 2024-08-18 15:03:51 字数 837 浏览 5 评论 0原文

所以我代表一个令牌环网络(在 SimPy 中进行模拟),我是 matplotlib 的新手,但我被告知它非常适合直观地表示我的模拟。

所以我在谷歌上搜索并找到了如何绘制形状和线条 - 分别使用 add_patch 和 add_line 到轴(我相信)。所以现在我有这个输出,绝对没问题:(

还不能发布图像!!) http://img137.imageshack.us/img137/7822/screenshot20100121at120.png

但我使用 pylab.show() 函数得到这个,我想我想要的是使用 pylab.plot() 函数实现这一点,这样我就可以使用 pylab.draw( )之后。

我的代码如下:

plab.ion()

plab.axes()

for circ in self.circleList:
    plab.gca().add_patch(circ)

for line in self.lineList:
    plab.gca().add_line(line)

plab.axis('scaled')
plab.show()

其中,circleList 和 lineList 是包含图表上的圆和线的列表,

我可能在这里误解了一些简单的东西,但我实际上找不到任何不明显基于图形的使用图的示例( ) 功能。


澄清:

如何使用 pylab.plot() 而不是 pylab.show() 获得相同的输出?

So I'm representing a token ring network (doing the simulation in SimPy), I'm a totally newbie to matplotlib, but I was told that it'd be really good for representing my simulation visually.

So I googled around and found out how to draw shapes and lines - using add_patch and add_line respectively to the axes (I believe). So now I have this output which is absolutely fine:

(can't post images yet!!)
http://img137.imageshack.us/img137/7822/screenshot20100121at120.png

But I'm getting this using the pylab.show() function, and what I think I want is to achieve this using the pylab.plot() function so that I can then update it as my simulation progresses using pylab.draw() afterward.

My code is as follows:

plab.ion()

plab.axes()

for circ in self.circleList:
    plab.gca().add_patch(circ)

for line in self.lineList:
    plab.gca().add_line(line)

plab.axis('scaled')
plab.show()

Where circleList and lineList are lists containing the circles and lines on the diagram

I'm probably misunderstanding something simple here, but I can't actually find any examples that aren't overtly graph based that use the plot() function.


Clarification:

How can I get that same output, using pylab.plot() instead of pylab.show() ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

分开我的手 2024-08-25 15:03:51

使用绘图方法复制图像:

from pylab import *

points = []
points.append((-0.25, -1.0))
points.append((0.7, -0.7))
points.append((1,0))
points.append((0.7,1))
points.append((-0.25,1.2))
points.append((-1,0.5))
points.append((-1,-0.5))
points.append((-0.25, -1.0))

a_line = plot(*zip(*points))[0]
a_line.set_color('g')
a_line.set_marker('o')
a_line.set_markerfacecolor('b')
a_line.set_markersize(30)
axis([-1.5,1.5,-1.5,1.5])

show()

根据注释进行编辑

这使用 python 多处理库在单独的进程中运行 matplotlib 动画。主进程使用队列将数据传递给它,然后更新绘图图像。

# general imports
import random, time
from multiprocessing import Process, Queue

# for matplotlib
import random
import numpy as np
import matplotlib
matplotlib.use('GTKAgg') # do this before importing pylab

import matplotlib.pyplot as plt
from matplotlib.patches import Circle


def matplotLibAnimate(q,points):

    # set up initial plot
    fig = plt.figure()
    ax = fig.add_subplot(111)


    circles = []
    for point in points:
        ax.add_patch(Circle(point,0.1))

    a_line, = ax.plot(*zip(*points))
    a_line.set_color('g')
    a_line.set_lw(2)

    currentNode = None  
    def animate(currentNode = currentNode):
        while 1:
            newNode = q.get()
            if currentNode: currentNode.remove()
            circle = Circle(newNode,0.1)
            currentNode = ax.add_patch(circle)
            circle.set_fc('r')
            fig.canvas.draw()

    # start the animation
    import gobject
    gobject.idle_add(animate)
    plt.show()

#initial points
points = ((-0.25, -1.0),(0.7, -0.7),(1,0),(0.7,1),(-0.25,1.2),(-1,0.5),(-1,-0.5),(-0.25, -1.0))
q = Queue()
p = Process(target = matplotLibAnimate, args=(q,points,))
p.start()

# feed animation data
while 1:
    time.sleep(random.randrange(4))
    q.put(random.sample(points,1)[0])

当然,完成此操作后,我认为 Whatnick 的图像解决方案会为您提供更好的服务。我会创建自己的 GUI,而不是使用内置于小部件中的 matplotlibs。然后,我通过生成 PNG 并交换它们来“动画化”我的 GUI。

Replicating your image using the plot method:

from pylab import *

points = []
points.append((-0.25, -1.0))
points.append((0.7, -0.7))
points.append((1,0))
points.append((0.7,1))
points.append((-0.25,1.2))
points.append((-1,0.5))
points.append((-1,-0.5))
points.append((-0.25, -1.0))

a_line = plot(*zip(*points))[0]
a_line.set_color('g')
a_line.set_marker('o')
a_line.set_markerfacecolor('b')
a_line.set_markersize(30)
axis([-1.5,1.5,-1.5,1.5])

show()

EDIT BASED ON COMMENTS

This uses python multiprocessing library to run the matplotlib animation in a separate process. The main process uses a queue to pass data to it which then updates the plot image.

# general imports
import random, time
from multiprocessing import Process, Queue

# for matplotlib
import random
import numpy as np
import matplotlib
matplotlib.use('GTKAgg') # do this before importing pylab

import matplotlib.pyplot as plt
from matplotlib.patches import Circle


def matplotLibAnimate(q,points):

    # set up initial plot
    fig = plt.figure()
    ax = fig.add_subplot(111)


    circles = []
    for point in points:
        ax.add_patch(Circle(point,0.1))

    a_line, = ax.plot(*zip(*points))
    a_line.set_color('g')
    a_line.set_lw(2)

    currentNode = None  
    def animate(currentNode = currentNode):
        while 1:
            newNode = q.get()
            if currentNode: currentNode.remove()
            circle = Circle(newNode,0.1)
            currentNode = ax.add_patch(circle)
            circle.set_fc('r')
            fig.canvas.draw()

    # start the animation
    import gobject
    gobject.idle_add(animate)
    plt.show()

#initial points
points = ((-0.25, -1.0),(0.7, -0.7),(1,0),(0.7,1),(-0.25,1.2),(-1,0.5),(-1,-0.5),(-0.25, -1.0))
q = Queue()
p = Process(target = matplotLibAnimate, args=(q,points,))
p.start()

# feed animation data
while 1:
    time.sleep(random.randrange(4))
    q.put(random.sample(points,1)[0])

Of course, after doing this I think you'll be better served with whatnick's image solution. I'd create my own GUI and not use matplotlibs built in widget. I'd then "animate" my GUI by generating PNGs and swapping them.

寂寞陪衬 2024-08-25 15:03:51

听起来 Mark 已经找到了您正在寻找的答案,但如果您决定采用 Whatnick 的方法并从单个 png 构建动画,这里是实现 Amit 使用 mencoder 建议的代码(来自 http://en.wikibooks.org/wiki/Mplayer):

mencoder mf://*.png -mf w=400:h=400 -ovc lavc -lavcopts vcodec=xvid -of avi -o output.avi

It sounds like Mark has the answer you were looking for, but if you decide to go with whatnick's approach and build an animation from individual pngs, here is the code to implement Amit's suggestion to use mencoder (from http://en.wikibooks.org/wiki/Mplayer):

mencoder mf://*.png -mf w=400:h=400 -ovc lavc -lavcopts vcodec=xvid -of avi -o output.avi
孤者何惧 2024-08-25 15:03:51

核心技术是使用set_data更新正在渲染的元素的数据。然后调用draw()。查看您的圆形和直线元素是否具有 set_data 函数。否则,您可以使用 pyvtk。另一个选项是渲染并将绘图保存为 png 文件,然后根据这些文件构建动画。

The core technique is to update the data of the elements being rendered using set_data. Then call draw(). See if your circle and line elements have set_data functions. Otherwise you can use pyvtk. The other option is to render and save the plots to png files and later build an animation from those.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文