Kích thước thùng trong Matplotlib (Biểu đồ)


149

Tôi đang sử dụng matplotlib để tạo biểu đồ.

Có cách nào để tự đặt kích thước của các thùng trái ngược với số lượng thùng không?

Câu trả lời:


270

Trên thực tế, nó khá dễ dàng: thay vì số lượng thùng bạn có thể đưa ra một danh sách với ranh giới bin. Chúng cũng có thể được phân phối không đồng đều:

plt.hist(data, bins=[0, 10, 20, 30, 40, 50, 100])

Nếu bạn chỉ muốn chúng được phân phối đều, bạn chỉ cần sử dụng phạm vi:

plt.hist(data, bins=range(min(data), max(data) + binwidth, binwidth))

Đã thêm vào câu trả lời gốc

Dòng trên chỉ hoạt động với datađầy đủ các số nguyên. Như macrocosme chỉ ra, đối với phao bạn có thể sử dụng:

import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))

20
thay thế phạm vi (...) bằng np.arange (...) để làm cho nó hoạt động với phao.
macrocosme

6
Thông tin ở đây là gì? Bạn đã đặt giá trị đó trước đây chưa?
UserYmY

1
Tôi tin rằng băng thông trong ví dụ này có thể được tìm thấy bởi : (data.max() - data.min()) / number_of_bins_you_want. Có + binwidththể thay đổi thành chỉ 1để làm cho điều này trở thành một ví dụ dễ hiểu hơn.
Jarad

2
Ngoài ra, đối với giải pháp tuyệt vời của CodingCat ở trên, đối với dữ liệu float, nếu bạn muốn các thanh biểu đồ tập trung quanh các dấu x số nguyên thay vì có các ranh giới thanh tại các dấu x, hãy thử điều chỉnh sau: bins = np.arange (dmin - 0,5, dmax + 0,5 + băng thông, độ rộng băng thông)
ngày

3
tùy chọn lw = 5, color = "white"hoặc tương tự chèn các khoảng trống màu trắng giữa các thanh
PatrickT

13

Đối với các thùng N, các cạnh của thùng được chỉ định bởi danh sách các giá trị N + 1 trong đó N đầu tiên cho các cạnh của thùng dưới và +1 cho cạnh trên của thùng cuối cùng.

Mã số:

from numpy import np; from pylab import *

bin_size = 0.1; min_edge = 0; max_edge = 2.5
N = (max_edge-min_edge)/bin_size; Nplus1 = N + 1
bin_list = np.linspace(min_edge, max_edge, Nplus1)

Lưu ý rằng linspace tạo mảng từ min_edge đến max_edge được chia thành các giá trị N + 1 hoặc N thùng


1
Lưu ý rằng các thùng được bao gồm giới hạn dưới và không bao gồm giới hạn trên của chúng, ngoại trừ thùng N + 1 (cuối cùng) bao gồm cả hai giới hạn.
lukewitmer

4

Tôi đoán cách dễ dàng sẽ là tính toán tối thiểu và tối đa của dữ liệu bạn có, sau đó tính toán L = max - min. Sau đó, bạn chia Lcho chiều rộng thùng mong muốn (Tôi giả sử đây là ý nghĩa của kích thước thùng) và sử dụng trần của giá trị này làm số thùng.


đó chính xác là những gì tôi đã nghĩ, cảm ơn. Đã tự hỏi nếu có một cách đơn giản hơn nhưng điều này dường như tìm thấy cảm ơn!
Sam Creamer

Sử dụng số tròn Tôi không có được kích thước thùng tròn với phương pháp này. Có ai có kinh nghiệm không?
Brad Urani

3

Tôi thích mọi thứ diễn ra tự động và để các thùng rơi vào các giá trị "tốt đẹp". Sau đây dường như làm việc khá tốt.

import numpy as np
import numpy.random as random
import matplotlib.pyplot as plt
def compute_histogram_bins(data, desired_bin_size):
    min_val = np.min(data)
    max_val = np.max(data)
    min_boundary = -1.0 * (min_val % desired_bin_size - min_val)
    max_boundary = max_val - max_val % desired_bin_size + desired_bin_size
    n_bins = int((max_boundary - min_boundary) / desired_bin_size) + 1
    bins = np.linspace(min_boundary, max_boundary, n_bins)
    return bins

if __name__ == '__main__':
    data = np.random.random_sample(100) * 123.34 - 67.23
    bins = compute_histogram_bins(data, 10.0)
    print(bins)
    plt.hist(data, bins=bins)
    plt.xlabel('Value')
    plt.ylabel('Counts')
    plt.title('Compute Bins Example')
    plt.grid(True)
    plt.show()

Kết quả có các thùng trên các khoảng đẹp của kích thước thùng.

[-70. -60. -50. -40. -30. -20. -10.   0.  10.  20.  30.  40.  50.  60.]

biểu đồ thùng tính toán


Chính xác những gì tôi đang tìm kiếm! Tuy nhiên, trong một số trường hợp, n_bins được làm tròn xuống do độ chính xác của dấu phẩy động. Ví dụ như cho desired_bin_size=0.05, min_boundary=0.850, max_boundary=2.05việc tính toán n_binstrở nên int(23.999999999999993)mà kết quả trong 23 thay vì 24 và do đó một bin quá ít. Làm tròn số trước khi chuyển đổi số nguyên làm việc cho tôi:n_bins = int(round((max_boundary - min_boundary) / desired_bin_size, 0)) + 1
M. Schlenker

3

Tôi sử dụng các lượng tử để làm đồng phục thùng và phù hợp với mẫu:

bins=df['Generosity'].quantile([0,.05,0.1,0.15,0.20,0.25,0.3,0.35,0.40,0.45,0.5,0.55,0.6,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1]).to_list()

plt.hist(df['Generosity'], bins=bins, normed=True, alpha=0.5, histtype='stepfilled', color='steelblue', edgecolor='none')

nhập mô tả hình ảnh ở đây


1
Ý tưởng tuyệt vời. Bạn có thể thay thế danh sách các lượng tử bằng np.arange(0, 1.01, 0.5)hoặc np.linspace(0, 1, 21). Không có cạnh, nhưng tôi hiểu các hộp có diện tích bằng nhau, nhưng chiều rộng khác nhau trong trục X?
Tomasz Gandor

2

Tôi có vấn đề tương tự như OP (tôi nghĩ vậy!), Nhưng tôi không thể làm cho nó hoạt động theo cách mà Lastalda đã chỉ định. Tôi không biết liệu tôi đã giải thích câu hỏi đúng chưa, nhưng tôi đã tìm thấy một giải pháp khác (có lẽ đó là một cách thực sự tồi tệ để làm điều đó).

Đây là cách mà tôi đã làm:

plt.hist([1,11,21,31,41], bins=[0,10,20,30,40,50], weights=[10,1,40,33,6]);

Điều này tạo ra điều này:

hình ảnh hiển thị biểu đồ biểu đồ được tạo trong matplotlib

Vì vậy, tham số đầu tiên về cơ bản là 'khởi tạo' thùng - Tôi đặc biệt tạo một số nằm trong phạm vi tôi đặt trong tham số thùng.

Để chứng minh điều này, hãy xem mảng trong tham số đầu tiên ([1,11,21,31,41]) và mảng 'thùng' trong tham số thứ hai ([0,10,20,30,40,50]) :

  • Số 1 (từ mảng đầu tiên) nằm trong khoảng từ 0 đến 10 (trong mảng 'thùng')
  • Số 11 (từ mảng đầu tiên) nằm trong khoảng từ 11 đến 20 (trong mảng 'thùng')
  • Số 21 (từ mảng đầu tiên) nằm trong khoảng từ 21 đến 30 (trong mảng 'thùng'), v.v.

Sau đó, tôi đang sử dụng tham số 'trọng lượng' để xác định kích thước của mỗi thùng. Đây là mảng được sử dụng cho tham số trọng số: [10,1,40,33,6].

Vì vậy, thùng 0 đến 10 được cho giá trị 10, thùng 11 đến 20 được cho giá trị 1, thùng 21 đến 30 được cho giá trị 40, v.v.


3
Tôi nghĩ rằng bạn có một sự hiểu lầm cơ bản về cách hoạt động của chức năng biểu đồ. Nó mong đợi dữ liệu thô. Vì vậy, trong ví dụ của bạn, mảng dữ liệu của bạn nên chứa 10 giá trị trong khoảng từ 0 đến 10, 1 giá trị trong khoảng từ 10 đến 20, v.v. Sau đó, hàm thực hiện tổng hợp VÀ bản vẽ. Những gì bạn đang làm ở trên là một cách giải quyết vì bạn đã có các khoản tiền (sau đó bạn chèn vào biểu đồ bằng cách sử dụng sai tùy chọn "trọng số"). Hy vọng điều này sẽ làm sáng tỏ một số nhầm lẫn.
CodingCat

-1

Đối với một biểu đồ có giá trị x số nguyên tôi đã kết thúc bằng cách sử dụng

plt.hist(data, np.arange(min(data)-0.5, max(data)+0.5))
plt.xticks(range(min(data), max(data)))

Độ lệch 0,5 tập trung vào các thùng trên các giá trị trục x. Cuộc plt.xticksgọi thêm một đánh dấu cho mỗi số nguyên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.