Làm cách nào tôi có thể vẽ các Pandas DataFrames riêng biệt dưới dạng các lô phụ?


129

Tôi có một vài Pandas DataFrame chia sẻ cùng thang giá trị, nhưng có các cột và chỉ số khác nhau. Khi gọi df.plot(), tôi nhận được các hình ảnh cốt truyện riêng biệt. những gì tôi thực sự muốn là có tất cả chúng trong cùng một cốt truyện như các cốt truyện phụ, nhưng tôi rất tiếc là không đưa ra được giải pháp cho cách thức và rất mong được trợ giúp.

Câu trả lời:


252

Bạn có thể tạo các ô con theo cách thủ công với matplotlib, sau đó vẽ các khung dữ liệu trên một ô con cụ thể bằng cách sử dụng axtừ khóa. Ví dụ cho 4 ô con (2x2):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)

df1.plot(ax=axes[0,0])
df2.plot(ax=axes[0,1])
...

Đây axeslà một mảng chứa các trục lô phụ khác nhau và bạn có thể truy cập một trục chỉ bằng cách lập chỉ mục axes.
Nếu bạn muốn một trục x được chia sẻ, thì bạn có thể cung cấp sharex=Truecho plt.subplots.


33
Lưu ý rằng, thật khó chịu, .subplots()trả về các hệ tọa độ khác nhau tùy thuộc vào kích thước của mảng ô con bạn đang tạo. Vì vậy, nếu bạn trả về các ô con, ví dụ nrows=2, ncols=1, bạn sẽ cần lập chỉ mục các trục là axes[0]axes[1]. Xem stackoverflow.com/a/21967899/1569221
canary_in_the_data_mine

3
@canary_in_the_data_mine Cảm ơn, đó là thực sự gây phiền nhiễu ... nhận xét của bạn đã cứu tôi một thời gian :) không thể tìm ra lý do tại sao tôi đã nhận đượcIndexError: too many indices for array
snd

9
@canary_in_the_data_mine Điều đó chỉ gây khó chịu nếu các đối số mặc định cho .subplot()được sử dụng. Đặt squeeze=Falseđể buộc .subplot()luôn trả về một ndarraytrong bất kỳ trường hợp nào của hàng và cột.
Martin

73

Bạn có thể xem e.gs. trong tài liệu chứng minh câu trả lời joris. Cũng từ tài liệu này, bạn cũng có thể đặt subplots=Truelayout=(,)trong plothàm pandas :

df.plot(subplots=True, layout=(1,2))

Bạn cũng có thể sử dụng fig.add_subplot()các tham số lưới ô ô con như 221, 222, 223, 224, v.v. như được mô tả trong bài đăng ở đây . Có thể thấy các ví dụ hay về âm mưu trên khung dữ liệu gấu trúc, bao gồm cả các ô con, trong sổ tay ipython này .


2
mặc dù câu trả lời của joris là rất tốt cho việc sử dụng matplotlib nói chung, điều này rất tuyệt vời cho bất kỳ ai muốn sử dụng gấu trúc để trực quan hóa dữ liệu nhanh chóng. Nó cũng phù hợp với câu hỏi hơn một chút.
Little Bobby Tables

Hãy nhớ rằng các subplotslayoutkwargs sẽ CHỈ tạo ra nhiều ô cho một khung dữ liệu duy nhất. Điều này liên quan đến, nhưng không phải là giải pháp cho câu hỏi của OP về việc vẽ nhiều khung dữ liệu vào một biểu đồ duy nhất.
Austin A

1
Đây là câu trả lời tốt hơn cho việc sử dụng Gấu trúc nguyên chất. Điều này không yêu cầu nhập trực tiếp matplotlib (mặc dù bạn vẫn nên làm như vậy) và không yêu cầu lặp lại các hình dạng tùy ý ( layout=(df.shape[1], 1)ví dụ: có thể sử dụng ).
Anatoly Makarevich

20

Bạn có thể sử dụng kiểu Matplotlib quen thuộc gọi a figuresubplot, nhưng bạn chỉ cần xác định trục hiện tại bằng cách sử dụng plt.gca(). Một ví dụ:

plt.figure(1)
plt.subplot(2,2,1)
df.A.plot() #no need to specify for first axis
plt.subplot(2,2,2)
df.B.plot(ax=plt.gca())
plt.subplot(2,2,3)
df.C.plot(ax=plt.gca())

Vân vân...


7

Bạn có thể vẽ nhiều ô con của nhiều khung dữ liệu gấu trúc bằng cách sử dụng matplotlib với một thủ thuật đơn giản là tạo danh sách tất cả khung dữ liệu. Sau đó, sử dụng vòng lặp for để vẽ các âm mưu phụ.

Mã làm việc:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# dataframe sample data
df1 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df2 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df3 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df4 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df5 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df6 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
#define number of rows and columns for subplots
nrow=3
ncol=2
# make a list of all dataframes 
df_list = [df1 ,df2, df3, df4, df5, df6]
fig, axes = plt.subplots(nrow, ncol)
# plot counter
count=0
for r in range(nrow):
    for c in range(ncol):
        df_list[count].plot(ax=axes[r,c])
        count=+1

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

Sử dụng mã này, bạn có thể vẽ các lô phụ trong bất kỳ cấu hình nào. Bạn chỉ cần xác định số hàng nrowvà số cột ncol. Ngoài ra, bạn cần lập danh sách các khung dữ liệu df_listmà bạn muốn vẽ biểu đồ.


2
chú ý đến lỗi đánh máy ở hàng cuối cùng: không phải count =+1nhưngcount +=1
PEBKAC

4

Bạn có thể sử dụng cái này:

fig = plt.figure()
ax = fig.add_subplot(221)
plt.plot(x,y)

ax = fig.add_subplot(222)
plt.plot(x,z)
...

plt.show()

3

Bạn có thể không cần sử dụng Pandas. Dưới đây là một biểu đồ matplotlib về tần số của mèo:

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

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

f, axes = plt.subplots(2, 1)
for c, i in enumerate(axes):
  axes[c].plot(x, y)
  axes[c].set_title('cats')
plt.tight_layout()

1

Dựa trên phản hồi @joris ở trên, nếu bạn đã thiết lập tham chiếu đến subplot, bạn cũng có thể sử dụng tham chiếu. Ví dụ,

ax1 = plt.subplot2grid((50,100), (0, 0), colspan=20, rowspan=10)
...

df.plot.barh(ax=ax1, stacked=True)

0

Cách tạo nhiều ô từ từ điển khung dữ liệu với dữ liệu dài (gọn gàng)

  • Giả định

    • Có một từ điển gồm nhiều khung dữ liệu chứa dữ liệu ngăn nắp
      • Được tạo bằng cách đọc từ tệp
      • Được tạo bằng cách tách một khung dữ liệu thành nhiều khung dữ liệu
    • Các danh mục, catcó thể chồng chéo, nhưng tất cả các khung dữ liệu có thể không chứa tất cả các giá trị củacat
    • hue='cat'
  • Bởi vì các khung dữ liệu đang được lặp đi lặp lại, không đảm bảo rằng các màu sẽ được ánh xạ giống nhau cho mỗi ô

    • Một bản đồ màu tùy chỉnh cần được tạo từ các 'cat'giá trị duy nhất cho tất cả các khung dữ liệu
    • Vì màu sắc sẽ giống nhau, hãy đặt một chú giải ở bên cạnh các ô, thay vì một chú giải trong mỗi ô

Nhập và dữ liệu tổng hợp

import pandas as pd
import numpy as np  # used for random data
import random  # used for random data
import matplotlib.pyplot as plt
from matplotlib.patches import Patch  # for custom legend
import seaborn as sns
import math import ceil  # determine correct number of subplot


# synthetic data
df_dict = dict()
for i in range(1, 7):
    np.random.seed(i)
    random.seed(i)
    data_length = 100
    data = {'cat': [random.choice(['A', 'B', 'C']) for _ in range(data_length)],
            'x': np.random.rand(data_length),
            'y': np.random.rand(data_length)}
    df_dict[i] = pd.DataFrame(data)


# display(df_dict[1].head())

  cat         x         y
0   A  0.417022  0.326645
1   C  0.720324  0.527058
2   A  0.000114  0.885942
3   B  0.302333  0.357270
4   A  0.146756  0.908535

Tạo ánh xạ màu và vẽ biểu đồ

# create color mapping based on all unique values of cat
unique_cat = {cat for v in df_dict.values() for cat in v.cat.unique()}  # get unique cats
colors = sns.color_palette('husl', n_colors=len(unique_cat))  # get a number of colors
cmap = dict(zip(unique_cat, colors))  # zip values to colors

# iterate through dictionary and plot
col_nums = 3  # how many plots per row
row_nums = math.ceil(len(df_dict) / col_nums)  # how many rows of plots
plt.figure(figsize=(10, 5))  # change the figure size as needed
for i, (k, v) in enumerate(df_dict.items(), 1):
    plt.subplot(row_nums, col_nums, i)  # create subplots
    p = sns.scatterplot(data=v, x='x', y='y', hue='cat', palette=cmap)
    p.legend_.remove()  # remove the individual plot legends
    plt.title(f'DataFrame: {k}')

plt.tight_layout()
# create legend from cmap
patches = [Patch(color=v, label=k) for k, v in cmap.items()]
# place legend outside of plot; change the right bbox value to move the legend up or down
plt.legend(handles=patches, bbox_to_anchor=(1.06, 1.2), loc='center left', borderaxespad=0)
plt.show()

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

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.