2010-11-04 34 views
80

Tôi gặp sự cố khi vẽ lại hình ở đây. Tôi cho phép người dùng chỉ định các đơn vị theo thang thời gian (trục x) và sau đó tôi tính toán lại và gọi hàm này plots(). Tôi muốn cốt truyện chỉ đơn giản là cập nhật, không nối thêm một cốt truyện khác vào hình.Làm thế nào để cập nhật một âm mưu trong matplotlib?

def plots(): 
    global vlgaBuffSorted 
    cntr() 

    result = collections.defaultdict(list) 
    for d in vlgaBuffSorted: 
     result[d['event']].append(d) 

    result_list = result.values() 

    f = Figure() 
    graph1 = f.add_subplot(211) 
    graph2 = f.add_subplot(212,sharex=graph1) 

    for item in result_list: 
     tL = [] 
     vgsL = [] 
     vdsL = [] 
     isubL = [] 
     for dict in item: 
      tL.append(dict['time']) 
      vgsL.append(dict['vgs']) 
      vdsL.append(dict['vds']) 
      isubL.append(dict['isub']) 
     graph1.plot(tL,vdsL,'bo',label='a') 
     graph1.plot(tL,vgsL,'rp',label='b') 
     graph2.plot(tL,isubL,'b-',label='c') 

    plotCanvas = FigureCanvasTkAgg(f, pltFrame) 
    toolbar = NavigationToolbar2TkAgg(plotCanvas, pltFrame) 
    toolbar.pack(side=BOTTOM) 
    plotCanvas.get_tk_widget().pack(side=TOP) 
+0

có thể trùng lặp của [thời gian thực âm mưu trong vòng lặp while với matplotlib] (http://stackoverflow.com/questions/11874767/real-time-plotting-in-while-loop-with-matplotlib) –

Trả lời

97

Bạn về cơ bản có hai lựa chọn:

  1. làm chính xác những gì bạn đang làm, nhưng gọi graph1.clear()graph2.clear() trước replotting dữ liệu. Đây là tùy chọn chậm nhất nhưng đơn giản nhất và mạnh mẽ nhất.

  2. Thay vì thay thế, bạn chỉ có thể cập nhật dữ liệu của đối tượng ô. Bạn sẽ cần thực hiện một số thay đổi trong mã của mình, nhưng điều này sẽ nhanh hơn nhiều, nhanh hơn nhiều so với việc thay thế mọi thứ. Tuy nhiên, hình dạng của dữ liệu mà bạn đang vẽ không thể thay đổi và nếu phạm vi dữ liệu của bạn đang thay đổi, bạn sẽ cần phải đặt lại theo cách thủ công giới hạn trục x và y.

Để đưa ra một ví dụ về sự lựa chọn thứ hai:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.linspace(0, 6*np.pi, 100) 
y = np.sin(x) 

# You probably won't need this if you're embedding things in a tkinter plot... 
plt.ion() 

fig = plt.figure() 
ax = fig.add_subplot(111) 
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma 

for phase in np.linspace(0, 10*np.pi, 500): 
    line1.set_ydata(np.sin(x + phase)) 
    fig.canvas.draw() 
+0

Tôi đã thử nghiệm "1." và kết quả là, sau khi tôi phát lại dữ liệu, một tập hợp lô khác đã được vẽ trong GUI của tôi, vì vậy bây giờ tôi đã có 4 ô sau khi tính toán lại, giống như trước đây. – thenickname

+0

@thenickname - Mã xác thực của bạn ở đâu trong mã của bạn? Bạn nên gọi 'graph1.clear(); graph2.clear() 'bên trong vòng lặp' for' của bạn, ngay trước khi bạn gọi 'graph1.plot (...)', 'graph2.plot (...)' etc ... –

+0

Điều đó cho vòng lặp tạo ra các biểu đồ callx. cốt truyện (...) N lần và đặt các câu nói rõ ràng trong đó chỉ có âm mưu cuối cùng. Tôi đã thực sự rút ra các mã vải và đặt nó vào vòng lặp chương trình chính cùng với mã số và bây giờ tôi có chức năng của tôi được gọi bằng một nút. Vì một lý do nào đó nếu tôi chỉ gọi chức năng, các ô được cập nhật, nhưng nếu tôi nhấn nút thì các ô không có. Đó là hành vi khá thú vị. Tôi nghĩ đó phải là một lỗi trong Tkinter. – thenickname

3

Tất cả những điều trên có thể đúng, tuy nhiên đối với tôi "trực tuyến cập nhật" của các nhân vật chỉ làm việc với một số backends, cụ thể wx. Bạn chỉ có thể cố gắng thay đổi điều này, ví dụ: bằng cách bắt đầu ipython/pylab bởi ipython --pylab=wx! Chúc may mắn!

+1

Cảm ơn bạn đã gửi thư, tôi chưa bao giờ sử dụng chế độ tương tác vì nó không bao giờ hoạt động với phần phụ trợ mặc định mà tôi đã sử dụng. Thật thú vị khi sử dụng chế độ tương tác hơn là ngừng thực hiện mỗi khi bạn muốn xem biểu đồ! – PierreE

+0

Không có câu trả lời nào khác giúp trong trường hợp của tôi. Tôi đang sử dụng pycharm và vấn đề là với âm mưu và tương tác của giao diện điều khiển. Tôi cần phải thêm Từ nhập pylab * và sau đó là ion() trong nội dung mã để bật tính năng tương tác. Nó hoạt động trơn tru cho tôi. – shev72

8

Trong trường hợp bất cứ ai đi qua bài viết này tìm kiếm những gì tôi đang tìm kiếm, tôi thấy ví dụ tại

How to visualize scalar 2D data with Matplotlib?

http://mri.brechmos.org/2009/07/automatically-update-a-figure-in-a-loop (on web.archive.org)

sau đó biến đổi chúng để sử dụng imshow với một đầu vào ngăn xếp của khung hình, thay vì tạo ra và sử dụng các đường nét trên bay.


Bắt đầu với một mảng hình ảnh 3D có hình dạng (nBins, nBins, nBins), được gọi là frames.

def animate_frames(frames): 
    nBins = frames.shape[0] 
    frame = frames[0] 
    tempCS1 = plt.imshow(frame, cmap=plt.cm.gray) 
    for k in range(nBins): 
     frame = frames[k] 
     tempCS1 = plt.imshow(frame, cmap=plt.cm.gray) 
     del tempCS1 
     fig.canvas.draw() 
     #time.sleep(1e-2) #unnecessary, but useful 
     fig.clf() 

fig = plt.figure() 
ax = fig.add_subplot(111) 

win = fig.canvas.manager.window 
fig.canvas.manager.window.after(100, animate_frames, frames) 

tôi cũng tìm thấy một cách đơn giản hơn nhiều để đi về toàn bộ quá trình này, mặc dù ít mạnh mẽ:

fig = plt.figure() 

for k in range(nBins): 
    plt.clf() 
    plt.imshow(frames[k],cmap=plt.cm.gray) 
    fig.canvas.draw() 
    time.sleep(1e-6) #unnecessary, but useful 

Lưu ý rằng cả hai dường như chỉ để làm việc với ipython --pylab=tk, aka backend = TkAgg

Cảm ơn bạn đã giúp đỡ với mọi thứ.

5

Tôi đã phát hành gói có tên python-drawnow cung cấp chức năng để cập nhật hình, thường được gọi trong vòng lặp for, tương tự như drawnow của Matlab.

Một cách sử dụng ví dụ:

from pylab import figure, plot, ion, linspace, arange, sin, pi 
def draw_fig(): 
    # can be arbitrarily complex; just to draw a figure 
    #figure() # don't call! 
    plot(t, x) 
    #show() # don't call! 

N = 1e3 
figure() # call here instead! 
ion() # enable interactivity 
t = linspace(0, 2*pi, num=N) 
for i in arange(100): 
    x = sin(2 * pi * i**2 * t/100.0) 
    drawnow(draw_fig) 

gói này làm việc với bất kỳ con số matplotlib và cung cấp tùy chọn để chờ sau mỗi lần cập nhật hình hoặc thả vào trình gỡ lỗi.

+1

Làm thế nào là nó mạnh mẽ và không ổn định cùng một lúc? – BlueMoon93

+1

Tôi có nghĩa là mạnh mẽ như trong "làm việc với bất kỳ con số matplotlib" và không ổn định như trong "dự án cuối tuần". Tôi đã cập nhật câu trả lời của tôi – Scott

12

Điều này phù hợp với tôi. Liên tục gọi một hàm cập nhật đồ thị mỗi lần.

import matplotlib.pyplot as plt 
import matplotlib.animation as anim 

def plot_cont(fun, xmax): 
    y = [] 
    fig = plt.figure() 
    ax = fig.add_subplot(1,1,1) 

    def update(i): 
     yi = fun() 
     y.append(yi) 
     x = range(len(y)) 
     ax.clear() 
     ax.plot(x, y) 
     print i, ': ', yi 

    a = anim.FuncAnimation(fig, update, frames=xmax, repeat=False) 
    plt.show() 

"fun" là hàm trả về số nguyên. FuncAnimation sẽ liên tục gọi "cập nhật", nó sẽ làm điều đó "xmax" lần.

+0

Bạn có thể đưa ra một ví dụ về cách bạn gọi hàm này (đặc biệt là cách bạn chuyển một hàm trong một cuộc gọi hàm) cũng như cách hàm fun() trông như thế nào? – bjornasm

+1

Chắc chắn. "fun()" là bất kỳ hàm nào trả về một số nguyên. Bạn có thể truyền hàm này làm đối số cho một đối số khác như sau: "plot_cont (my_function, 123)". Có bạn gọi cho tôi plot_cont tại dòng 86: https://github.com/vitobasso/audio-ml/blob/bbb3f633ef3638406912d6f75a8c6a7311aea3fc/src/train_spec.py – Vituel

-1
import csv 
import sys 
import getopt 
import socket 
import time 
import numpy as np 
import matplotlib 
from scipy.misc import imread 
from matplotlib import pyplot as plt 
import warnings 
fig, ax = plt.subplots() 
ax.set_xlim(-158, 553) 
ax.set_ylim(-290, 733) 
im = plt.imread("") 
plt.imshow(img, zorder=0, extent=[0.5, 8.0, 1.0, 7.0]) 

fig.show() 
l_global=[] 
points=[] 
master_tag_csvlink='c:/logfolde.log.csv' 
csvfile=open(master_tag_csvlink, 'r') 
for ainfo in csvfile: 
     line= ainfo 
     l_list= list(line.split('_')) 
     l_local=[] 
     for i in range(int(l_list[0])): 
      l_local.append(list(l_list[i+1].split(','))) 
     function1= lambda x,i: x[i] # return list[n,X] of elements at x 
     c= lambda x,l: [x for i in range(l) if True] 
     for i in range(len(l_local)): 
      l_local[i][1],l_local[i][2]=int(l_local[i][1]),int(l_local[i][2]) 

     if l_global: #In begining l_glocal is empty, so just copy the data in to l_global 
      l_global=l_local[:] 
      for i in range(len(l_global)): 
       points.append(plt.plot(function1(l_global[i],1),function1(l_global[i],2),'g',label="Tag:%s, X:%f, y: %f"%(function1(l_global[i],0),function1(l_global[i],1),function1(l_global[i],2)))) 



     else: # compare the l_local & l_global for any updates 
      tag_Id=map(function1,l_local,c(0,len(l_local))) #list of list of tagId,x,y TagId is filtered - local 
      mTag_Id=map(fuction1,l_global,c(0,len(l_global))) #list of list of tagId,x,y TagId is filtered - master 

      for i in mTag_Id: 
       if i not in tag_Id: #comparing master tags and tag_Id's 
        index=mTag_Id.index(i) ############### Tags in master list but not in Tag_id 
        copy_point=l_global[index] 
        [removing_point]=points[index]######## means tag is in-active ,turn tag color into red 
        removing_point.remove() 
        del points[index] 

        points.insert(index,plt.plot(function1(l_global[index],1),function1(l_global[index],2),'r',label="Tag:%s, X:%f, y: %f"%(function1(l_global[i],0),function1(l_global[i],1),function1(l_global[i],2)))) 

       elif i in tag_Id: # append the tag into l_global 
        index=mTag_Id.index(i) ############### Tags in master list but not in Tag_id 
        l_global[index]=l_local[index][:] 
        [removing_point]=points[index]######## means tag is active update coordinates 
        removing_point.remove() 
        del points[index] 
        points.insert(index,plt.plot(function1(l_global[index],1),function1(l_global[index],2),'g',label="Tag:%s, X:%f, y: %f"%(function1(l_global[i],0),function1(l_global[i],1),function1(l_global[i],2)))) 
      for i in Tag_Id: 
       if i not in mTag_Id: 
        index=Tag_Id(i) 
        l_global.append(l_local[index]] 
        points.append(plt.plot(function1(l_global[-1],1),function1(l_global[-1],2),'g',label="Tag:%s, X:%f, y: %f"%(function1(l_global[i],0),function1(l_global[i],1),function1(l_global[i],2)))) 

# import matplotlib.pyplot as plt 
# import numpy as np 

# x = np.linspace(0, 6*np.pi, 100) 
# y = np.sin(x) 

# # You probably won't need this if you're embedding things in a tkinter plot... 
# plt.ion() 

# fig = plt.figure() 
# ax = fig.add_subplot(11)1 
# line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma 

# for phase in np.linspace(0, 10*np.pi, 500): 
    # line1.set_ydata(np.sin(x + phase)) 
    # fig.canvas.draw() 
+0

Điều này có thêm bất kỳ thứ gì vào năm câu trả lời đã được đăng ? Nếu có, tôi khuyên bạn nên chỉnh sửa nó để giảm mã xuống mức tối thiểu cần thiết để hiển thị điều đó. Chào mừng bạn đến với trang web, nhân tiện. – user2699

Các vấn đề liên quan