【问题标题】:Matplotlib excessive memory useMatplotlib 内存使用过多
【发布时间】:2014-04-14 03:21:42
【问题描述】:

下面给出的是从文件中读取值并绘制它们的代码。我正在阅读大约 36000 个值。我正在使用 matplotlib 绘制它们。如果值低于某个阈值,我将删除并旋转我为绘图制作的网格。

def readdata():
    global mul
    global fig
    global S
    global flag
    global k
    global line_number
    global readcount
    global angle_deviate
    global true_counter
    global fail_flag
    global loop_count
    global ts
    global xlist
    global ylist
    while k<S:
        line_number=line_number+1
        line=linecache.getline("data.txt", line_number)
        if line_number==1:
            x=float(line)*math.cos(0)
            y=float(line)*math.sin(0)
            xlist.append(300+x)
            ylist.append(300+y)
        else:
            x=float(line)*math.cos((readcount-1)*mul/samp_rate)
            y=float(line)*math.sin((readcount-1)*mul/samp_rate)
            xlist.append(300+x)
            ylist.append(300+y)
        plt.plot(xlist, ylist, lw=1, color='#ee8d18')
        if true_counter <(samp_rate*t[k]): #true counter to determine if the stage is complete or not
            if k<S-1 and k!=S-1:
                if p[k]<float(line):
                    true_counter=true_counter+1
                    fail_flag=1
                    point=plt.plot(300+x, 300+y, '.', markersize=3, color='#ee8d18')
                    loop_count+=1
                    pts.append(point)
                    readcount+=1
                    plt.pause(0.1) #first pause in plotting for 0.1 seconds
                    continue
                else:
                    readcount+=1
                    true_counter=0
                    point=plt.plot(300+x, 300+y, '.', markersize=3, color='#ee8d18')
                    loop_count+=1
                    pts.append(point)
                    plt.pause(0.1) #first pause in plotting for 0.1 seconds
                    deleteplot(k, fail_flag, loop_count)
            if k==S-1:
                if p[k]<float(line):
                    readcount+=1
                    true_counter=true_counter+1
                    x=float(line)*math.cos((readcount-1)*mul/samp_rate)
                    y=float(line)*math.sin((readcount-1)*mul/samp_rate)
                    point=plt.plot(300+x, 300+y, '.', markersize=3, color='#ee8d18')
                    loop_count+=1
                    pts.append(point)
                    plt.pause(0.1) #first pause in plotting for 0.1 seconds
                    continue
                else:
                    readcount+=1
                    true_counter=0
                    point=plt.plot(300+x, 300+y, '.', markersize=3, color='#ee8d18')
                    loop_count+=1
                    pts.append(point)
                    plt.pause(0.1) #first pause in plotting for 0.1 seconds
                    deleteplot(k, fail_flag, loop_count)
        else:
            true_counter=0
            k+=1
            fail_flag=0
            line_number=line_number-1
            loop_count=0
            i=0
            while i<S+1:
                cumulative_theta[i]=rotate_theta[i]
                i+=1

问题是这段代码像任何东西一样使用内存。它从 30MB 开始,一个小时左右增加到 260-300 MB。如何减少内存使用量?我还能做些什么来减少 CPU 的负载和内存中断?

【问题讨论】:

  • 这个问题似乎是题外话,因为它属于codereview.stackexchange.com
  • 乍一看,它可能与重复的情节陈述有关。要更新绘图,请执行hh = plt.plot(x,y) 之类的操作用于初始绘图,hh[0].set_daty(x1,y1) 用于更新线条。
  • @Dietrich pyplot() 究竟做了什么?它会再次指向所有点吗?还是存储点的位置?
  • plt.plot() 绘制传递给它的点 - 所有现有点都保留在现有(子)图中。 set_data()(不是set_daty,对不起)替换一行的现有数据。所以你确实得到了相当多的开销,如果你绘制的每个点,你都会生成一个新的线对象plot()。尝试plt.gca().get_children() 找出您的绘图中存在多少线条对象。
  • 我会首先摆脱所有的全局变量...

标签: python matplotlib rotation


【解决方案1】:

我怀疑你想要这样的东西:

from matplotlib import pyplot as plt

# make figure + axes
fig, ax = plt.subplots(1, 1)
# make base line
ln, = ax.plot([], [], 'r')
for j in range(50):
      # get current data
      x_data = list(ln.get_xdata())
      y_data = list(ln.get_ydata())
      # append new data, or do what ever you want to it

      x_data.append(j)
      y_data.append(j * j)
      # to keep just last n points, x_data = x_data[-n:]
      # set data of existing line
      ln.set_xdata(x_data)
      ln.set_ydata(y_data)
      # auto-scale the view limits
      ax.relim()
      ax.autoscale()
      # force the canvas to redraw
      plt.draw()
      # pause to give the gui time to refresh
      plt.pause(.1)

不会在内部循环中创建任何新对象,只是更新现有对象。

我还会查看animation 模块示例。

【讨论】:

  • 非常感谢您的回答。我会尽快试试这个。我确实查看了animation 模块。问题是我在所有这些示例中只看到了 1 个要动画的对象,在这里我想动画不止一件东西。在显示这一点的文档中没有找到任何示例。你知道我在哪里可以找到这样的例子吗?
  • 好吧,我试过了,嗯,内存以同样的方式增加,以同样的速度增加。我还能做什么?
  • 编写 最简单 示例,该示例将重现此问题并编辑您的问题以显示该代码。除此之外,我能做的最好的就是猜测。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 2012-09-12
  • 2018-04-01
相关资源
最近更新 更多