2012-10-24 29 views
14

Tôi đang tạo một vài ô pdf với matplotlib bao gồm 400 ô con. Mỗi người chỉ có 5 điểm dữ liệu. Phải mất 420 s trên một máy tính tốt để tiết kiệm 5 hình ảnh pdf. Có cách nào để tối ưu hóa mã hoặc nó chỉ là bình thường đối với matplotlib?matplotlib rất chậm. Nó có bình thường không?

Phần mã cho âm mưu:

plot_cnt = 1 
for k in np.arange(K_min, K_max + 1): 
    for l in np.arange(L_min, L_max + 1): 
     ax = plt.subplot(grid[0], grid[1], plot_cnt) 
     plot_cnt += 1 
     plt.setp(ax, 'frame_on', False) 
     ax.set_ylim([-0.1, 1.1]) 
     ax.set_xlabel('K={},L={}'.format(k, l), size=3) 
     ax.set_xlim([-0.1, 4.1]) 
     ax.set_xticks([]) 
     ax.set_yticks([]) 
     ax.grid('off') 
     ax.plot(np.arange(5), (data['S1']['Azimuth'][:, k - 1, l + offset_l] + \ 
       data['S1']['Delta Speed'][:, k - 1, l + offset_l] + \ 
       data['S1']['Speed'][:, k - 1, l + offset_l])/3, 
       'r-o', ms=1, mew=0, mfc='r') 
     ax.plot(np.arange(5), data['S2'][case][:, k - 1, l + offset_l], 
       'b-o', ms=1, mew=0, mfc='b') 
plt.savefig(os.path.join(os.getcwd(), 'plot-average.pdf')) 
plt.clf() 
print 'Final plot created.' 

Ảnh cuối cùng: enter image description here

+3

400 điểm phụ có vẻ là rất nhiều đối với tôi. Ngay cả khi bạn không có nhiều dữ liệu, matplotlib có thể không được tối ưu hóa để hiển thị loại lưới này. – Simon

+1

@Simon, là nó có thể âm mưu bằng cách sử dụng một subplot lớn duy nhất? Sau đó, mỗi năm nên được kết nối. Bất kỳ ý tưởng? – rowman

+0

Tôi không có môi trường phù hợp để chạy thử nghiệm, nhưng có một vài điều bạn có thể làm. Bước đầu tiên là chạy profiler trên mã của bạn (xem [here] (http://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script) để biết thêm thông tin). Với điều này, bạn có thể xác định vị trí thời gian được sử dụng. Hai điều bạn có thể thử là tìm một số tài nguyên để phát hành ở từng bước hoặc để tạo các ô trong một số quy trình bằng cách sử dụng [đa xử lý] (http://docs.python.org/library/multiprocessing.html). Nếu tôi tìm thấy thời gian tôi sẽ cố gắng này, nhưng ở giai đoạn này tôi không thể đảm bảo bất cứ điều gì – Simon

Trả lời

20

Building tắt của những gì @rowman nói, bạn có thể làm điều này tất cả trong một trục (như bạn tắt tất cả các ve v.v.) Một cái gì đó như:

K_max = 20 
K_min = 0 
L_max = 20 
L_min = 0 
ax = plt.subplot(111) 
x_offset = 7 # tune these 
y_offset = 7 # tune these 
plt.setp(ax, 'frame_on', False) 
ax.set_ylim([0, (K_max-K_min +1)*y_offset ]) 
ax.set_xlim([0, (L_max - L_min+1)*x_offset]) 
ax.set_xticks([]) 
ax.set_yticks([]) 
ax.grid('off') 



for k in np.arange(K_min, K_max + 1): 
    for l in np.arange(L_min, L_max + 1): 
     ax.plot(np.arange(5) + l*x_offset, 5+rand(5) + k*y_offset, 
       'r-o', ms=1, mew=0, mfc='r') 
     ax.plot(np.arange(5) + l*x_offset, 3+rand(5) + k*y_offset, 
       'b-o', ms=1, mew=0, mfc='b') 
     ax.annotate('K={},L={}'.format(k, l), (2.5+ (k)*x_offset,l*y_offset), size=3,ha='center') 
plt.savefig(os.path.join(os.getcwd(), 'plot-average.pdf')) 

print 'Final plot created.' 

Chạy trong khoảng một hoặc hai giây. Tôi nghĩ rằng tất cả thời gian được dành cho việc thiết lập đối tượng axes khá phức tạp trong nội bộ. output with fake data

+0

Rất đẹp. Chỉ cần ra khỏi sự tò mò, có thể sử dụng kỹ thuật được đề cập ở đây (http://www.scipy.org/Cookbook/Matplotlib/Animations) không? Chỉ cần sử dụng 'set_ydata' của dòng. Nên tìm một phương pháp để sao chép các đối tượng rìu. – rowman

+0

@rowman bạn có thể cụ thể hơn về phương pháp nào tại liên kết đó không? Nếu bạn muốn tạo ra 400 con số riêng biệt 'set_ydata' sẽ hữu ích, nhưng tôi không thấy ngay lập tức nó sẽ hữu ích trong trường hợp này. – tacaswell

+0

Đối với các ứng dụng GUI, tôi chỉ tạo một dòng và cập nhật Y chỉ để nhanh thay vì vẽ lại toàn bộ hình mỗi lần. Trong trường hợp này, tôi chỉ nghĩ thay vì tạo ra 400 hình, sao chép một đối tượng 400 lần, cập nhật Y và vị trí của trục hình. Nó có thể mất cùng một thời gian mặc dù. – rowman

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