2012-01-16 21 views
7

Tôi đang cố gắng in biểu đồ 600 dpi bằng cách sử dụng Python matplotlib. Tuy nhiên Python vẽ 2 trong số 8 biểu đồ, và đầu ra các lỗi:Matplotlib Agg Rendering Complexity Error

OverflowError: Agg rendering complexity exceeded. Consider downsampling or decimating your data. 

Tôi đang âm mưu một lượng lớn dữ liệu (7.500.000 dữ liệu cho mỗi cột) vì vậy tôi đoán hoặc là sẽ có một số vấn đề quá tải hay rằng tôi cần phải đặt một cell_block_limit lớn.

Tôi đã thử tìm kiếm các giải pháp thay đổi cell_block_limit trên Google nhưng không có kết quả. Điều gì sẽ là một cách tiếp cận tốt?

Mã như sau: -

 import matplotlib.pyplot as plt 
     from matplotlib.ticker import MultipleLocator, FormatStrFormatter 

     majorLocator = MultipleLocator(200) 
     majorFormatter = FormatStrFormatter('%d') 
     minorLocator = MultipleLocator(20) 

     fig = plt.figure() 
     ax = fig.add_subplot(111) 
     ax.xaxis.set_major_locator(majorLocator) 
     ax.xaxis.set_major_formatter(majorFormatter) 
     ax.xaxis.set_minor_locator(minorLocator) 
     ax.xaxis.set_ticks_position('bottom') 
     ax.xaxis.grid(True,which='minor') 
     ax.yaxis.grid(True) 
     plt.plot(timemat,fildata) 
     plt.xlabel(plotxlabel,fontsize=14) 
     plt.ylabel(plotylabel,fontsize=14)  
     plt.title(plottitle,fontsize=16) 
     fig.savefig(plotsavetitle,dpi=600) 
+0

đó là rất nhiều dữ liệu, xem xét một 1600x1200 sẽ phải 'chỉ' 1.920.000 _pixels_ trong đó. bạn đang cố tạo ra loại âm mưu nào? Nếu đó là một biểu đồ bạn có thể bin chúng, một dòng có thể được subsampled .. – wim

+0

đó là dữ liệu từ gia tốc lấy mẫu tại 1500 Hz để chụp sốc tần số cao. Tôi đang cố gắng để làm cho điện áp đơn giản (V) vs Thời gian cốt truyện. Vì vậy, trước tiên tôi tạo ra số lượng dữ liệu tương tự cho một mảng thời gian và vẽ biểu đồ tín hiệu theo thời gian. Có nó rất lớn nhưng trong tương lai tôi chắc chắn nó sẽ nhận được thậm chí rất lớn kể từ khi chúng tôi đang làm một 2 giờ đến 4 giờ thử nghiệm. Xin vui lòng cho tôi biết làm thế nào để subsample một dòng ... cảm ơn bạn rất nhiều! –

+1

sử dụng một lát trên đầu vào (trên cả hai trục). ví dụ, để chọn mỗi phần tử thứ 10 của một mảng 'x' bạn sẽ sử dụng' x [:: 10] ' – wim

Trả lời

15

Ngoài điểm của @ Lennart mà không cần đến độ phân giải đầy đủ, bạn cũng có thể xem xét một âm mưu tương tự như sau.

Tính max/nghĩa/phút của một "chửi rủa" phiên bản rất đơn giản và hiệu quả nếu bạn sử dụng một cái nhìn 2D của mảng gốc và arg axis từ khóa để x.min(), x.max() vv

Ngay cả với việc lọc, vẽ đồ thị này nhanh hơn nhiều so với vẽ toàn bộ mảng.

(Lưu ý: để vẽ nhiều điểm này, bạn sẽ phải điều chỉnh mức độ tiếng ồn một chút. Nếu không, bạn sẽ nhận được OverflowError bạn đã đề cập. Nếu bạn muốn so sánh âm mưu của tập dữ liệu "đầy đủ", hãy thay đổi y += 0.3 * y.max() np.random... dòng để giống như 0.1 hoặc loại bỏ nó hoàn toàn.)

import matplotlib.pyplot as plt 
import numpy as np 
np.random.seed(1977) 

# Generate some very noisy but interesting data... 
num = 1e7 
x = np.linspace(0, 10, num) 
y = np.random.random(num) - 0.5 
y.cumsum(out=y) 
y += 0.3 * y.max() * np.random.random(num) 

fig, ax = plt.subplots() 

# Wrap the array into a 2D array of chunks, truncating the last chunk if 
# chunksize isn't an even divisor of the total size. 
# (This part won't use _any_ additional memory) 
chunksize = 10000 
numchunks = y.size // chunksize 
ychunks = y[:chunksize*numchunks].reshape((-1, chunksize)) 
xchunks = x[:chunksize*numchunks].reshape((-1, chunksize)) 

# Calculate the max, min, and means of chunksize-element chunks... 
max_env = ychunks.max(axis=1) 
min_env = ychunks.min(axis=1) 
ycenters = ychunks.mean(axis=1) 
xcenters = xchunks.mean(axis=1) 

# Now plot the bounds and the mean... 
ax.fill_between(xcenters, min_env, max_env, color='gray', 
       edgecolor='none', alpha=0.5) 
ax.plot(xcenters, ycenters) 

fig.savefig('temp.png', dpi=600) 

enter image description here

+1

SUPERB! Cách vô cùng giàu thông tin và sáng tạo để xem dữ liệu! +++ –

3

Với 600dpi bạn sẽ phải thực hiện những âm mưu rộng để mưu dữ liệu mà không decimating nó 13 mét. :-)

Tôi khuyên bạn nên chia nhỏ dữ liệu thành nhiều phần một vài trăm hoặc thậm chí có thể là một nghìn mẫu và kéo giá trị tối đa ra khỏi đó.

Something như thế này:

def chunkmax(data, chunk_size): 
    source = iter(data) 
    chunk = [] 
    while True: 
     for i in range(chunk_size): 
      chunk.append(next(source)) 

     yield max(chunk) 

này sẽ sau đó, với một chunk_size 1000 cung cấp cho bạn 7500 điểm để vẽ, nơi bạn sau đó có thể dễ dàng nhìn thấy nơi trong các dữ liệu cú sốc đến. (Trừ khi dữ liệu quá ồn ào, bạn sẽ phải tính trung bình nó để xem liệu có bị mắc kẹt hay không. Nhưng điều đó cũng dễ dàng sửa chữa được).

+0

Cảm ơn bạn! Có vẻ như không có cách nào khác để vẽ một âm mưu dpi cao. –

+1

FYI: Trong khi đó là một gợi ý tuyệt vời, mã thực tế ở trên là rất không hiệu quả cho mảng numpy. được tốt hơn làm một cái gì đó như 'chunks = data.reshape ((- 1, chunk_size)); max_filtered = chunks.max (axis = 1)'. (Giả sử trường hợp đơn giản, nơi kích thước chunk là một ước số thậm chí của tổng kích thước ... Ví dụ tổng quát chỉ là một hoặc hai dòng phụ.) –

+0

@JoeKington: Ồ, anh ta sử dụng numpy? Tôi không hiểu điều đó. Thực sự đang lặp đi lặp lại trên một mảng không đầy đủ không hiệu quả? Oh well. –