Panda 将两个具有多个列的数据框放入单个箱线图中

问题描述 投票:0回答:1

所以我有 2 个数据框,每个都有多个列:

1 2 3 4 5
0.11 1.12 12.32
1.48 0.03 0.32 17.85
0.56 0.95 8.35
0.09 2.31 0.32 1.04 5.46

另一张与此类似,填充了一些其他数据。我需要在 1 个图上绘制这 2 个数据框。每列都是不同的 x 轴索引值。我正在使用 pandas.DataFrame.boxplot() 方法,因为它是真正绘制数据而不跳过任何内容的唯一方法(matplotlib.boxplot() 似乎只绘制了数据的一部分,不知道为什么)。

问题在于,依次调用多个 df.boxplot() 会导致错误:

File "analysis_script.py", line 387, in <module>
    df.boxplot()
  File "pandas\plotting\_core.py", line 516, in boxplot_frame
    return plot_backend.boxplot_frame(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "pandas\plotting\_matplotlib\boxplot.py", line 458, in boxplot_frame
    ax = boxplot(
         ^^^^^^^^
  File "pandas\plotting\_matplotlib\boxplot.py", line 437, in boxplot
    result = plot_group(columns, data.values.T, ax, **kwds)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "bpandas\plotting\_matplotlib\boxplot.py", line 376, in plot_group
    assert remainder == 0, remainder
           ^^^^^^^^^^^^^^
AssertionError: 1

这是我的代码部分:

match index:
    case 0:
        fig, ax = plt.subplots()
        df.boxplot()
    case 1:
        df.boxplot()

        min_y = min_y_8h - 0.25 * abs(min_y_8h)
        max_y = max_y_8h + 1.25 * abs(max_y_8h)

        x_ticks = plt.xticks()[0]
        x_labels = [str(int(tick)) for tick in x_ticks if int(tick) % 3 == 0]
        plt.xticks(x_ticks[x_ticks % 3 == 0], x_labels, rotation=45)
        plt.xlim(2.5, 23.5)
        plt.ylim(min_y, max_y)
        plt.show()
        plt.close()

它在循环中运行,因此 df 变量在每次迭代中都是不同的 df,并且索引变量有许多功能,在本例中,它用于监视正在绘制哪些数据。

python pandas dataframe boxplot
1个回答
0
投票

AssertionError: 1
可能是由于您使用循环创建的不同数据帧之间的列数不匹配。

我尝试重现该问题,并且使用几个最小的数据帧确实遇到了相同的问题。我试图解决这个问题 - 使用 matplotlib

 的箱线图从同一轴上的多个数据帧绘制箱线图,它似乎可以解决问题:

import pandas as pd import matplotlib.pyplot as plt import numpy as np # random dfs df1 = pd.DataFrame(np.random.rand(10, 4), columns=['A', 'B', 'C', 'D']) df2 = pd.DataFrame(np.random.rand(10, 3), columns=['E', 'F', 'G']) dfs = [df1, df2] # Create a figure and axes outside the loop fig, ax = plt.subplots() # Initial position for the first dataframe's boxplot position = 1 for df in dfs: # plot the dataframe using Matplotlib's boxplot ax.boxplot([df[col].dropna() for col in df.columns], positions=range(position, position + len(df.columns))) # update position position += len(df.columns) ax.set_xticks(range(1, position)) ax.set_xticklabels(['A', 'B', 'C', 'D', 'E', 'F', 'G'], rotation=45) ax.set_xlim(0.5, position - 0.5) plt.show()
我们不知道循环之外发生了什么,但使用这种方法它应该看起来像这样。这不是一个有效的示例,因为我没有您使用的数据,但它是基于您的代码的骨架:

import matplotlib.pyplot as plt # Assuming 'dfs' is a list of your dataframes dfs = [...] # Initialize the position for the first boxplot position = 1 for index, df in enumerate(dfs): match index: case 0: fig, ax = plt.subplots() # Plot using Matplotlib's boxplot ax.boxplot([df[col].dropna() for col in df.columns], positions=range(position, position + len(df.columns))) # Update the position for the next dataframe position += len(df.columns) case 1: # Plot using Matplotlib's boxplot ax.boxplot([df[col].dropna() for col in df.columns], positions=range(position, position + len(df.columns))) # Update the position for the next dataframe position += len(df.columns) # Your additional settings min_y = min_y_8h - 0.25 * abs(min_y_8h) max_y = max_y_8h + 1.25 * abs(max_y_8h) x_ticks = ax.get_xticks() x_labels = [str(int(tick)) for tick in x_ticks if int(tick) % 3 == 0] ax.set_xticks(x_ticks[x_ticks % 3 == 0]) ax.set_xticklabels(x_labels, rotation=45) ax.set_xlim(2.5, position - 0.5) ax.set_ylim(min_y, max_y) # Show the plot plt.show() plt.close()
当您尝试从多个 dfs 生成单个图时,我还将 

show()

close()
 放在循环之外,这更有意义。

© www.soinside.com 2019 - 2024. All rights reserved.