1

I'm trying to make WindRoses for the four seasons of the year on the same plot. I tried to follow the method from Subplot of Windrose in matplotlib but the method did not work for me.

I also tried the following from https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subplots_demo.html: (the index is in the DateTime format).

df = df.between_time('8:00', '21:00') #day
#df = df.between_time() #night
spring = df[~df.index.month.isin([1,2,6,7,8,9,10,11,12])] #spring
summer = df[~df.index.month.isin([1,2,3,4,5,9,10,11,12])] #summer
fall = df[~df.index.month.isin([1,2,3,4,5,6,7,8,12])] #fall
winter = df[~df.index.month.isin([3,4,5,6,7,8,9,10,11])] #winter


#sonny bono

x = [spring.ws_5408,summer.ws_5408,fall.ws_5408,winter.ws_5408]
y = [spring.dir_5408,summer.dir_5408,fall.dir_5408,winter.dir_5408]
ws1 = spring.ws_5408
wd1 = spring.dir_5408
ws2 = summer.ws_5408
wd2 = summer.dir_5408
ws3 = fall.ws_5408
wd3 = fall.dir_5408
ws4 = winter.ws_5408
wd4 = winter.dir_5408
#fig = 'SonnyBono_rose.png'

ax = WindroseAxes.from_ax()
fig, ax = plt.subplots(2, 2)
ax[0, 0].bar(ws1, wd1, normed=True, opening=0.8, edgecolor='white', bins=np.arange(0, 15, 3),cmap=cm.rainbow, nsector=20)
ax[0, 0].set_title('Spring')
ax[0, 1].bar(ws2, wd2, normed=True, opening=0.8, edgecolor='white', bins=np.arange(0, 15, 3),cmap=cm.rainbow, nsector=20)
ax[0, 1].set_title('Summer')
ax[1, 0].bar(ws3, wd3, normed=True, opening=0.8, edgecolor='white', bins=np.arange(0, 15, 3),cmap=cm.rainbow, nsector=20)
ax[1, 0].set_title('Fall')
ax[1, 1].bar(ws4, wd4, normed=True, opening=0.8, edgecolor='white', bins=np.arange(0, 15, 3),cmap=cm.rainbow, nsector=20)
ax[1, 1].set_title('Winter')
ax.set_legend(decimal_places=1, units='m/s',fontsize='x-large', loc='best')

I get an error message that says AttributeError: 'Rectangle' object has no property 'normed'. This code also doesn't give me four wind roses in a subplot but instead outputs four blank scatterplots. I'm not sure what to do. My dataframe can be found on this link: https://drive.google.com/file/d/1B2SiNfOVZt9zJ_XTHfl61Ngp7UiWAD16/view?usp=sharing

rpanai
  • 12,515
  • 2
  • 42
  • 64
obscuredbyclouds
  • 189
  • 1
  • 1
  • 15
  • Hi Heater, do you mind to share your `df`. It will be better if you provide a [mcve](/help/mcve). – rpanai Sep 02 '21 at 04:17
  • I did provide my dataframe it's in the google drive link at the very end – obscuredbyclouds Sep 02 '21 at 04:21
  • 1
    @Heather a minimal example means one just has to copy/paste your code and it runs. Requiring to download a file, typing in the commands to load it etc. means that many answerers will just skip your question and go to another one. You should read [this](https://stackoverflow.com/questions/20109391/how-to-make-good-reproducible-pandas-examples) – mozway Sep 02 '21 at 04:48
  • Did you realize you are overwriting `ax`? – rpanai Sep 02 '21 at 13:53

1 Answers1

1

I managed to reproduce your question. Please keep in mind @mozway suggestion about mcve for your next questions.

Prepare data

I downloaded locally your data in my working direction.

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.cm as cm
import windrose 


df = pd.read_csv("allregions_wind_hourly.csv")

# I keep only the columns we are going to use
# you can check with df.memory_usage(deep=True).sum()/1024**2
# how much RAM is your data using
cols_to_keep = ["date", "ws_5408", "dir_5408"]
df = df[cols_to_keep]

# Convert to datetime and extract season
df["date"] = df["date"].astype("M8")
df["season"] = df["date"].dt.month%12 //3 +1

season_dict = {1: "winter", 2: "spring", 
               3: "summer", 4: "autumn"}
df["season"] = df["season"].map(season_dict)
# Filter
df = df.set_index("date")
df = df.between_time('8:00', '21:00') #day

Regarding seasons I used this answer.

Plot

seasons = [v for k,v in season_dict.items()]
bins=np.arange(0, 15, 3)
nrows, ncols = 2, 2
fig = plt.figure(figsize=(15, 15))
# plt.subplots_adjust(hspace=0.5)
fig.tight_layout()
for i, season in enumerate(seasons):
    d =  df[df["season"].eq(season)].reset_index(drop=True)
    ax = fig.add_subplot(nrows, ncols, i + 1, projection="windrose")
    ax.set_title(season.capitalize(),fontsize=14, weight='bold')
    ax.bar(d["dir_5408"], d["ws_5408"],
           normed=True, opening=0.8,
           bins=bins, cmap=cm.rainbow,
           nsector=20)

enter image description here

EDIT: in case you need a sort of interactive plot you can consider using plotly. Here an example of windrose

EDIT2: In case you really want to share the dataframe you should consider saving the cleaned one to parquet and push to your github account and share the link so one can read it directly from Jupyter. The cleaned dataframe in parquet it's about 69x smaller than your original csv. Finally here you can find several examples of windrose usage.

rpanai
  • 12,515
  • 2
  • 42
  • 64