Reputation: 15
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'
Upvotes: 0
Views: 5658
Reputation: 80534
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()
Upvotes: 1