2015-02-15 17 views
5

Tôi đang tạo các ô tiêu chuẩn Matplotlib bằng lệnh plt.boxplot(). dòng của tôi về mã tạo các boxplot là:Ô chữ Matplotlib chỉ hiển thị các ô chữ tối đa và min

bp = plt.boxplot(data, whis=[5, 95], showfliers=True) 

Bởi vì dữ liệu của tôi có một bản phân phối lớn, tôi nhận được rất nhiều tờ quảng cáo bên ngoài phạm vi của râu. Để có được một âm mưu chất lượng xuất bản sạch hơn, tôi muốn chỉ hiển thị các tờ rơi đơn lẻ ở mức tối đa. và vào phút giá trị của dữ liệu, thay vì tất cả các tờ rơi. Điều này có thể không? Tôi không thấy bất kỳ tùy chọn tích hợp nào trong tài liệu hướng dẫn để thực hiện việc này.

(Tôi có thể đặt phạm vi của râu để tối đa/phút, nhưng đây không phải là những gì tôi muốn. Tôi muốn giữ râu ở phần trăm thứ 5 và 95).

Dưới đây là hình tôi đang làm việc. Chú ý mật độ của tờ bướm. Boxplots

+0

Mà không phải là mật độ phát tờ rơi thông tin quan trọng? – tacaswell

+0

Vâng, chắc chắn là. Phụ thuộc vào những gì bạn đang cố gắng để hiển thị tôi giả sử. Nhưng bạn làm cho một điểm tốt. – PJW

Trả lời

3

plt.boxplot() trả về một từ điển, trong đó khóa fliers chứa các chữ cái trên và dưới dưới dạng đối tượng line2d. Bạn có thể thao tác chúng trước khi âm mưu như thế này:

Chỉ trên matplotlib> = 1.4.0

bp = plt.boxplot(data, whis=[5, 95], showfliers=True) 

# Get a list of Line2D objects, representing a single line from the 
# minimum to the maximum flier points. 
fliers = bp['fliers'] 

# Iterate over it! 
for fly in fliers: 
    fdata = fly.get_data() 
    fly.set_data([fdata[0][0],fdata[0][-1]],[fdata[1][0],fdata[1][-1]]) 

Mở phiên bản cũ

Nếu bạn đang ở trên một phiên bản cũ của matplotlib, các tờ rơi cho mỗi ô được thể hiện bằng hai dòng, không phải một. Như vậy, vòng lặp sẽ giống như thế này:

import numpy as np 
for i in range(len(fliers)): 
    fdata = fliers[i].get_data() 
    # Get the index of the maximum y in data if 
    # i is 0 or even, else get index of minimum y. 
    if i%2 == 0: 
     id = np.where(fdata[1] == fdata[1].max())[0][0] 
    else: 
     id = np.where(fdata[1] == fdata[1].min())[0][0] 
    fliers[i].set_data([fdata[0][id], fdata[1][id]]) 

Cũng lưu ý rằng đối số showfliers không tồn tại trong matplotlib < 1.4x và lập luận whisk không chấp nhận danh sách.

Dĩ nhiên (cho các ứng dụng đơn giản), bạn có thể vẽ đồ thị boxplot mà không phát tờ rơi và thêm tối đa và điểm tối thiểu để cốt truyện:

bp = plt.boxplot(data, whis=[5, 95], showfliers=False) 
sc = plt.scatter([1, 1], [data.min(), data.max()]) 

nơi [1, 1] là x-vị trí của các điểm.

+0

Giải pháp đầu tiên của bạn vẽ tất cả các tờ rơi tối đa tốt, nhưng không phải là min. Nếu tôi phụ trong min cho tối đa trong mã, sau đó chỉ là âm mưu phút. Có lẽ tôi đang thiếu một cái gì đó, nhưng làm thế nào để có được cả tối đa và min để âm mưu? Giải pháp được đề xuất thứ hai không hoạt động .... vẽ một số điểm bên dưới các hộp, nhưng chúng không phải là phút. Và giải pháp được đề xuất thứ ba sẽ không làm việc cho tôi, vì 'dữ liệu' thực sự là một danh sách của nhiều khung dữ liệu Pandas (sản xuất nhiều ô giống như trong hình đã đăng). Cảm ơn câu trả lời của bạn mặc dù, tôi nghĩ rằng nó là rất gần! – PJW

+0

Xin lỗi, hôm qua hơi quá muộn. Tôi đã sửa nó ở trên. Hy vọng nó là hợp lý rõ ràng và dễ làm theo. Cũng đã đưa ra gợi ý thứ hai. – Geotob

+0

Bây giờ, thay thế tối thiểu và tối đa, chẳng hạn hộp 1 chỉ hiển thị tối đa, hộp 2 chỉ hiển thị phút, hộp 3 chỉ hiển thị tối đa, v.v ... ?? Xem hình tôi đã thêm ở trên. – PJW

1
fliers = bp['fliers'] 
for i in range(len(fliers)): # iterate through the Line2D objects for the fliers for each boxplot 
    box = fliers[i] # this accesses the x and y vectors for the fliers for each box 
    box.set_data([[box.get_xdata()[0],box.get_xdata()[0]],[np.min(box.get_ydata()),‌​np.max(box.get_ydata())]]) 
    # note that you can use any two values from the xdata vector 

Kết quả con số, chỉ hiển thị max và min tờ quảng cáo: enter image description here

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