2013-04-27 64 views
8

Tôi có một số cảm biến gắn với Raspberry Pi của tôi; Tôi đang gửi dữ liệu của họ đến máy tính của tôi hai lần một giây bằng cách sử dụng TCP. Tôi muốn liên tục vẽ đồ thị các giá trị này bằng cách sử dụng matplotlib. Phương pháp tôi hiện đang sử dụng có vẻ không hiệu quả (tôi đang xóa subplot và vẽ lại nó mỗi lần) và có một số nhược điểm không mong muốn (quy mô được điều chỉnh mọi thời gian; Tôi muốn nó ở lại từ 0,0 - 5,0). Tôi biết có một cách để làm điều này mà không cần phải rõ ràng và vẽ lại nhưng dường như không thể tìm ra. Sau đây là mã hiện tại của tôi:Tự động cập nhật âm mưu thanh trong matplotlib

import socket 
import sys 
import time 
from matplotlib import pyplot as plt 

# Create a TCP/IP socket 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# Connect the socket to the port where the server is listening 
server_address = ('192.168.0.10', 10000) 
print >>sys.stderr, 'connecting to %s port %s' % server_address 
sock.connect(server_address) 

# Initial setup for the bar plot 
plt.ion() 
fig = plt.figure() 
ax = fig.add_subplot(1,1,1) 
x = [1,2,3] 
labels = ['FSR', 'Tilt', 'IR'] 
ax.set_xticklabels(labels) 
y = [5.0,5.0,5.0] 
ax.bar(x,y) 
fig.autofmt_xdate() 
plt.draw() 

#Grab and continuously plot sensor values 
try: 
    for i in range(300): 
     amount_received = 0 
     amount_expected = len("0.00,0.00,0.00") 

     # Receive data from RasPi 
     while amount_received < amount_expected: 
      data = sock.recv(14) 
      amount_received += len(data) 
      print >>sys.stderr, 'received "%s"' % data 

     # Plot received data 
     y = [float(datum) for datum in data.split(',')] 
     ax.clear() 
     ax.bar(x,y) 
     plt.draw() 
     time.sleep(0.5) 

#Close the socket  
finally: 
    print >>sys.stderr, 'closing socket' 
    sock.close() 

Trả lời

16

Bạn có thể sử dụng animation.FuncAnimation. Lô cốt truyện thanh một lần và lưu các giá trị trả về, mà là một bộ sưu tập các rects:

rects = plt.bar(range(N), x, align='center') 

Sau đó, để thay đổi chiều cao của một quán bar, gọi rect.set_height:

for rect, h in zip(rects, x): 
     rect.set_height(h) 

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

def animate(frameno): 
    x = mu + sigma * np.random.randn(N) 
    n, _ = np.histogram(x, bins, normed=True) 
    for rect, h in zip(patches, n): 
     rect.set_height(h) 
    return patches 

N, mu, sigma = 10000, 100, 15 
fig, ax = plt.subplots() 
x = mu + sigma * np.random.randn(N) 
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='green', alpha=0.75) 

frames = 100 
ani = animation.FuncAnimation(fig, animate, blit=True, interval=0, 
           frames=frames, 
           repeat=False) 
plt.show() 
2

Nếu matplotlib không phải là tùy chọn bắt buộc, tôi sẽ đề xuất Hệ thống đẩy dựa trên cổng trên máy chủ và bản vẽ dựa trên Javascript cho phía máy khách. Tôi sẽ liệt kê một vài ưu điểm đầu tiên:

  1. Client (PC khác của bạn) chỉ phải có một trình duyệt web hiện đại được cài đặt và có thể chạy bất kỳ hệ điều hành và không cần phải có Python, Matplotlib cài đặt
  2. Kể từ WebSockets sẽ làm việc theo cách phát sóng, bạn có thể có số lượng khách hàng sử dụng cùng một nguồn cấp dữ liệu, có thể rất hữu ích trong khi cho phép người dùng có bản demo của hệ thống của bạn
  3. Mã phía máy khách cũng hiệu quả, nó giữ lại các giá trị 'x' cuối cùng và hoạt động tốt trong thời gian thực, vì vậy mọi thứ không cần phải được vẽ lại

Vì tôi đang làm một cái gì đó rất giống với Raspberry Pi của tôi, tôi có thể chia sẻ các chi tiết của tôi giống nhau. Nó được lấy cảm hứng từ bài đăng blog this. Mã cho phía máy chủ đẩy dữ liệu có thể được tìm thấy here. Bạn có thể thấy rằng sau khi cài đặt các phụ thuộc, nó rất giống với mã của bạn và cuối cùng bạn sẽ tìm thấy socket.send() ngay cả trong mã của tôi. Đối với phía máy khách, this là liên kết đến tệp HTML và this là JS được thực thi trên trình duyệt, sử dụng Flot Thư viện vẽ. Tôi chắc chắn bản demo trên trang chủ của họ đủ tuyệt vời để được chú ý!

+0

Rất cám ơn vì điều này, tôi sẽ xem xét để thực hiện điều này như là một bản nâng cấp. Tuy nhiên, tôi vẫn muốn biết nếu có một sửa chữa đơn giản cho vấn đề ban đầu của tôi với việc cập nhật biểu đồ matplotlib mà không cần thanh toán bù trừ? – hfaran

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