Làm thế nào để vẽ biểu đồ bằng Matplotlib trong Python với một danh sách dữ liệu?


100

Tôi đang cố gắng vẽ biểu đồ bằng cách sử dụng matplotlib.hist()hàm nhưng tôi không chắc chắn về cách thực hiện.

Tôi có một danh sách

probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]

và một danh sách các tên (chuỗi).

Làm cách nào để đặt xác suất là giá trị y của mỗi thanh và đặt tên là giá trị x?

Câu trả lời:


168

Nếu bạn muốn có một biểu đồ, bạn không cần phải đính kèm bất kỳ 'tên' nào cho các giá trị x, vì trên trục x, bạn sẽ có các thùng dữ liệu:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
np.random.seed(42)
x = np.random.normal(size=1000)
plt.hist(x, density=True, bins=30)  # `density=False` would make counts
plt.ylabel('Probability')
plt.xlabel('Data');

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

Bạn có thể làm cho biểu đồ của mình đẹp hơn một chút với PDFdòng, tiêu đề và chú thích:

import scipy.stats as st
plt.hist(x, density=True, bins=30, label="Data")
mn, mx = plt.xlim()
plt.xlim(mn, mx)
kde_xs = np.linspace(mn, mx, 301)
kde = st.gaussian_kde(x)
plt.plot(kde_xs, kde.pdf(kde_xs), label="PDF")
plt.legend(loc="upper left")
plt.ylabel('Probability')
plt.xlabel('Data')
plt.title("Histogram");

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

Tuy nhiên, nếu bạn có số lượng điểm dữ liệu hạn chế, chẳng hạn như trong OP, một biểu đồ thanh sẽ có ý nghĩa hơn để đại diện cho dữ liệu của bạn (sau đó bạn có thể đính kèm nhãn vào trục x):

x = np.arange(3)
plt.bar(x, height=[1,2,3])
plt.xticks(x, ['a','b','c'])

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


4
Hãy nhớ, không có dấu chấm phẩy ở cuối dòng trong python!
Toad22222

10
@ Toad22222 Đây là một đoạn trích từ ô máy tính xách tay Ipython. Hãy thử thực hiện nó mà không có dấu chấm phẩy và xem sự khác biệt. Tất cả các đoạn mã tôi đăng trên SO đều chạy hoàn hảo trên máy tính của tôi.
Sergey Bushmanov

2
Nếu bạn đang thắc mắc về dấu chấm phẩy được Sergey sử dụng, hãy xem tại đây# 16 tại đây để biết cách sử dụng dấu chấm phẩy trong các ô của sổ ghi chép Jupyter (trước đây là sổ ghi chép IPython) khi cố gắng loại bỏ văn bản về đối tượng cốt truyện.
Wayne

19

Nếu bạn chưa cài đặt matplotlib, chỉ cần thử lệnh.

> pip install matplotlib

Nhập thư viện

import matplotlib.pyplot as plot

Dữ liệu biểu đồ:

plot.hist(weightList,density=1, bins=20) 
plot.axis([50, 110, 0, 0.06]) 
#axis([xmin,xmax,ymin,ymax])
plot.xlabel('Weight')
plot.ylabel('Probability')

Hiển thị biểu đồ

plot.show()

Và đầu ra như sau:

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


2
Dòng plot.axis ([50, 110, 0, 0,06]) 'là vô dụng đối với ví dụ. Bên cạnh đó, vì nó khó mã hóa khu vực của âm mưu để hiển thị, nếu dữ liệu của bạn không nằm hoàn toàn bên trong nó, bạn có thể bối rối tại sao nó không hiển thị chính xác.
typhon04

10

Mặc dù câu hỏi dường như yêu cầu vẽ biểu đồ bằng cách sử dụng matplotlib.hist() hàm, nó có thể được cho là không được thực hiện bằng cách sử dụng giống như phần sau của câu hỏi yêu cầu sử dụng các xác suất đã cho dưới dạng giá trị y của các thanh và tên đã cho (chuỗi) như giá trị x.

Tôi giả sử một danh sách mẫu gồm các tên tương ứng với các xác suất đã cho để vẽ biểu đồ. Một biểu đồ thanh đơn giản phục vụ mục đích ở đây cho bài toán đã cho. Có thể sử dụng mã sau:

import matplotlib.pyplot as plt
probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]
names = ['name1', 'name2', 'name3', 'name4', 'name5', 'name6', 'name7', 'name8', 'name9',
'name10', 'name11', 'name12', 'name13'] #sample names
plt.bar(names, probability)
plt.xticks(names)
plt.yticks(probability) #This may be included or excluded as per need
plt.xlabel('Names')
plt.ylabel('Probability')

5

Đây là một câu hỏi cũ nhưng không có câu trả lời nào trước đây đề cập đến vấn đề thực sự, tức là thực tế rằng vấn đề nằm ở chính câu hỏi.

Đầu tiên, nếu xác suất đã được tính toán, tức là dữ liệu tổng hợp biểu đồ có sẵn theo cách chuẩn hóa thì xác suất sẽ cộng lại bằng 1. Rõ ràng là không và điều đó có nghĩa là có điều gì đó không ổn ở đây, với thuật ngữ hoặc dữ liệu hoặc theo cách đặt câu hỏi.

Thứ hai, thực tế là các nhãn được cung cấp (chứ không phải khoảng thời gian) thông thường sẽ có nghĩa là các xác suất thuộc biến phản ứng phân loại - và việc sử dụng một biểu đồ thanh để vẽ biểu đồ là tốt nhất (hoặc một số hack phương pháp lịch sử của pyplot), Câu trả lời của Shayan Shafiq cung cấp mã.

Tuy nhiên, hãy xem vấn đề 1, những xác suất đó không đúng và việc sử dụng biểu đồ thanh trong trường hợp này là "biểu đồ" sẽ sai vì nó không kể câu chuyện về phân phối đơn biến, vì một số lý do (có lẽ các lớp chồng chéo và các quan sát được tính nhiều lần?) và âm mưu như vậy không được gọi là biểu đồ trong trường hợp này.

Biểu đồ theo định nghĩa là một biểu diễn đồ họa của sự phân bố của biến đơn biến (xem https://www.itl.nist.gov/div898/handbook/eda/section3/histogra.htm , https://en.wikipedia.org/wiki /Biểu đồ) và được tạo ra bằng cách vẽ các thanh có kích thước biểu thị số lượng hoặc tần số quan sát trong các lớp được chọn của biến quan tâm. Nếu biến được đo trên thang đo liên tục thì các lớp đó là thùng (khoảng). Phần quan trọng của quy trình tạo biểu đồ là lựa chọn cách nhóm (hoặc giữ mà không nhóm) các danh mục phản hồi cho một biến phân loại hoặc cách chia miền của các giá trị có thể thành các khoảng (nơi đặt ranh giới bin) cho liên tục biến kiểu. Tất cả các quan sát phải được thể hiện và mỗi quan sát chỉ một lần trong biểu đồ. Điều đó có nghĩa là tổng kích thước thanh phải bằng tổng số lượng quan sát (hoặc diện tích của chúng trong trường hợp chiều rộng thay đổi, đây là cách tiếp cận ít phổ biến hơn). Hoặc, nếu biểu đồ được chuẩn hóa thì tất cả các xác suất phải cộng với 1.

Nếu bản thân dữ liệu là một danh sách các "xác suất" như một phản hồi, tức là các quan sát là giá trị xác suất (của một cái gì đó) cho mỗi đối tượng nghiên cứu thì câu trả lời tốt nhất chỉ đơn giản là plt.hist(probability)có thể có tùy chọn binning và sử dụng các nhãn x đã có sẵn là đáng ngờ.

Khi đó, biểu đồ thanh không nên được sử dụng làm biểu đồ mà chỉ đơn giản là

import matplotlib.pyplot as plt
probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]
plt.hist(probability)
plt.show()

với kết quả

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

matplotlib trong trường hợp như vậy đến theo mặc định với các giá trị biểu đồ sau

(array([1., 1., 1., 1., 1., 2., 0., 2., 0., 4.]),
 array([0.31308411, 0.32380469, 0.33452526, 0.34524584, 0.35596641,
        0.36668698, 0.37740756, 0.38812813, 0.39884871, 0.40956928,
        0.42028986]),
 <a list of 10 Patch objects>)

kết quả là một bộ nhiều mảng, mảng đầu tiên chứa số lượng quan sát, tức là những gì sẽ được hiển thị so với trục y của biểu đồ (chúng cộng lại tối đa 13, tổng số quan sát) và mảng thứ hai là khoảng giới hạn của x -axis.

Người ta có thể kiểm tra chúng cách đều nhau,

x = plt.hist(probability)[1]
for left, right in zip(x[:-1], x[1:]):
  print(left, right, right-left)

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

Hoặc, ví dụ: đối với 3 thùng (gọi theo phán đoán của tôi cho 13 quan sát) một thùng sẽ nhận được biểu đồ này

plt.hist(probability, bins=3)

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

với dữ liệu âm mưu "đằng sau song sắt" là

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

Tác giả của câu hỏi cần phải làm rõ ý nghĩa của danh sách giá trị "xác suất" là gì - "xác suất" chỉ là tên của biến phản hồi (vậy tại sao lại có các nhãn x sẵn sàng cho biểu đồ, điều đó không có ý nghĩa gì ), hoặc là các giá trị danh sách xác suất được tính toán từ dữ liệu (khi đó thực tế là chúng không cộng đến 1 sẽ không có ý nghĩa gì).


4

Đây là một cách làm rất vòng vo nhưng nếu bạn muốn tạo một biểu đồ trong đó bạn đã biết các giá trị bin nhưng không có dữ liệu nguồn, bạn có thể sử dụng np.random.randinthàm để tạo số lượng giá trị chính xác trong phạm vi của mỗi bin cho hàm hist để vẽ biểu đồ, ví dụ:

import numpy as np
import matplotlib.pyplot as plt

data = [np.random.randint(0, 9, *desired y value*), np.random.randint(10, 19, *desired y value*), etc..]
plt.hist(data, histtype='stepfilled', bins=[0, 10, etc..])

đối với nhãn, bạn có thể căn chỉnh x tick với các thùng để có được một cái gì đó như sau:

#The following will align labels to the center of each bar with bin intervals of 10
plt.xticks([5, 15, etc.. ], ['Label 1', 'Label 2', etc.. ])
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.