简体   繁体   中英

“AttributeError: 'DataFrameGroupBy' object has no attribute 'get'” when attempting to box plot grouped data in Seaborn's .boxplot()

I asked this earlier but it was moved to this question as it was similar, however, this isn't the output I wanted. I know you can group boxplots, but the boxplots themselves should be separate. I'm grouping a bunch of data by weekday (from 0 to 6, so seven groups in total) and I want to have those 7 boxplots on one plot. I'm using Seaborn's boxplot function for this:

sns.boxplot(data=concentration_by_weekday, x = 'weekday', y='NO2', ax=ax[1,0]);

It should be returning 7 boxplots, one for each day of the week. The dataframe should return 7 groups (which it does, if I use .describe() ) I instead get this error: AttributeError: 'DataFrameGroupBy' object has no attribute 'get' .

The syntax should be correct, however, the dataframe I am using ( concentration_by_weekday ) is a DataFrameGroupBy object. The concentration_by_weekday dataframe is grouped by weekday as follows:

concentration_by_weekday = df_data[data_mask_4].groupby('weekday')

The data mask being used is just one that I've used for my other subplots (the other ones plot correctly, but they aren't boxplots, so it shouldn't be an issue with the data mask). I know it should be possible to plot multiple boxplots on one graph, I'm just not sure if this is the right syntax. I've included the relevant code snippet below:

data_mask_4 = (df_data['year'] != 2020)

concentration_by_weekday = df_data[data_mask_4].groupby('weekday')
#concentration_by_year = df_data[data_mask_4].groupby('year')
#concentration_by_year = concentration_by_year[['NO2', 'year']]

fig, ax = plt.subplots(ncols=2, nrows = 2, figsize=(17, 7))

#... plotting line graphs on [0,0] and [0,1] ...

sns.boxplot(data=concentration_by_weekday, x = 'weekday', y = 'NO2', ax=ax[1,0]);
sns.boxplot(data=concentration_by_year, x='weekday', y='NO2', ax=ax[1,1]);

Here is the full error that is displayed:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-67-cd5ffc1652e3> in <module>
     23 ax[0,1].plot(df_aq_quartiles_month['75%']);
     24 
---> 25 sns.boxplot(data=concentration_by_weekday, x = 'weekday', y = 'NO2', ax=ax[1,0]);
     26 #sns.boxplot(data=concentration_by_year, x='weekday', y='NO2', ax=ax[1,1]);

D:\Users\adcar\anaconda3\lib\site-packages\seaborn\categorical.py in boxplot(x, y, hue, data, order, hue_order, orient, color, palette, saturation, width, dodge, fliersize, linewidth, whis, ax, **kwargs)
   2239     plotter = _BoxPlotter(x, y, hue, data, order, hue_order,
   2240                           orient, color, palette, saturation,
-> 2241                           width, dodge, fliersize, linewidth)
   2242 
   2243     if ax is None:

D:\Users\adcar\anaconda3\lib\site-packages\seaborn\categorical.py in __init__(self, x, y, hue, data, order, hue_order, orient, color, palette, saturation, width, dodge, fliersize, linewidth)
    441                  width, dodge, fliersize, linewidth):
    442 
--> 443         self.establish_variables(x, y, hue, data, orient, order, hue_order)
    444         self.establish_colors(color, palette, saturation)
    445 

D:\Users\adcar\anaconda3\lib\site-packages\seaborn\categorical.py in establish_variables(self, x, y, hue, data, orient, order, hue_order, units)
    141             # See if we need to get variables from `data`
    142             if data is not None:
--> 143                 x = data.get(x, x)
    144                 y = data.get(y, y)
    145                 hue = data.get(hue, hue)

D:\Users\adcar\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py in __getattr__(self, attr)
    578 
    579         raise AttributeError(
--> 580             f"'{type(self).__name__}' object has no attribute '{attr}'"
    581         )
    582 

AttributeError: 'DataFrameGroupBy' object has no attribute 'get'

And here is an output of the dataframe itself, if I use concentration_by_weekday['NO2', 'weekday'].head() -- the dataframe has 33 columns so it's too large to show the whole thing, and I only need these two variables from it at the moment. Note that it does work as expected when using describe() .

You could let seaborn do the grouping. It is one of its fortes. So, directly sns.boxplot(data=df, x='weekday', y='NO2') .

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

N = 100
df_data = pd.DataFrame({'year': np.random.randint(2015, 2021, N),
                        'weekday': np.random.randint(0, 7, N),
                        'NO2': np.random.uniform(5, 40, N)})
year_filter = df_data['year'] != 2020

fig, axes = plt.subplots(ncols=2, squeeze=False)
sns.boxplot(data=df_data[year_filter], x='weekday', y='NO2', ax=axes[0, 0])
sns.boxplot(data=df_data[year_filter], x='year', y='NO2', ax=axes[0, 1])
plt.tight_layout()
plt.show()

示例图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM