I am trying to make pollution windroses using the Windrose library. I have 5 sites and want to create one figure per each site (denoted by the four digit number at the end of the column name), but each figure will have 12 pollution windrose subplots that correspond to each month. I have a working code but I have to run it individually for each site and want to make a loop that will allow for me to make a figure for each site in one run. The problem is, in order to make a subplot for each month, I have a for loop
that is interfering with the other loop that will allow for multiple figures to be prepared in one run. Here is the code:
import pandas as pd
from windrose import WindroseAxes
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
wr = pd.read_csv('')
wr["date"] = wr["date"].astype("M8")
wr["Month"] = wr.date.dt.month
month_dict = {1: "January", 2: "February", 3: "March", 4: "April",
5: "May", 6: "June", 7: "July", 8: "August", 9: "September",
10: "October", 11: "November", 12: "December"}
wr["Month"] = wr["Month"].map(month_dict)
# Filter
wr = wr.set_index("date")
wr = wr.between_time('6:00', '18:00') #day
xval = ["dir_3168", "dir_5405", "dir_5409", "dir_5407", "dir_5408", "dir_3135"]
yval = ["pm25_3168", "pm25_5405", "pm25_5409", "pm25_5407", "pm25_5408", "pm25_3135"]
fnames_day = ['Banning_PM25_monthly_day.png','Torres_PM25_monthly_day.png','NTB_PM25_monthly_day.png',
'BB_PM25_monthly_day.png','SB_PM25_monthly_day.png']
months = [v for k,v in month_dict.items()]
nrows, ncols = 2,6
fig = plt.figure(figsize=(30, 10))
bins=np.arange(0, 60, 12) #pm2.5
fig.tight_layout()
for i, month in enumerate(months):
d = wr[wr["Month"].eq(month)].reset_index(drop=True)
ax = fig.add_subplot(nrows, ncols, i 1, projection="windrose")
ax.set_title(month.capitalize(),fontsize=20, weight='bold')
for x,y,fname in zip(xval,yval,fnames_day):
ax.bar(d[x], d[y],
normed=True, opening=0.8,
bins=bins, cmap=cm.rainbow,
nsector=16)
ax.set_xticklabels(['E', 'N-E', 'N', 'N-W', 'W', 'S-W', 'S', 'S-E'],fontsize=18)
#ax.set_yticks(np.arange(11, 77, step=11))
ax.tick_params(axis="y", labelsize=18)
#ax.figure.savefig(fname, dpi=400)
Here's a link to the csv file: https://drive.google.com/file/d/1CanA2IlCo0AotnX_uEafw2vfIW38rVvd/view?usp=sharing
Currently the code only produces one figure, meaning there is something wrong with the first for loop
.
CodePudding user response:
I slightly altered the loops (I switched the loops around, nesting the month loop in the site loop, and added the fig
lines into the loop):
#...
months = [v for k,v in month_dict.items()]
nrows, ncols = 2,6
for x, y, fname in zip(xval, yval, fnames_day):
fig = plt.figure(figsize=(30, 10))
bins=np.arange(0, 60, 12) #pm2.5
fig.tight_layout()
for i, month in enumerate(months):
d = wr[wr["Month"].eq(month)].reset_index(drop=True)
ax = fig.add_subplot(nrows, ncols, i 1, projection="windrose")
ax.set_title(month.capitalize(),fontsize=20, weight='bold')
ax.bar(d[x], d[y],
normed=True, opening=0.8,
bins=bins, cmap=cm.rainbow,
nsector=16)
ax.set_xticklabels(['E', 'N-E', 'N', 'N-W', 'W', 'S-W', 'S', 'S-E'],fontsize=18)
#ax.set_yticks(np.arange(11, 77, step=11))
ax.tick_params(axis="y", labelsize=18)
ax.figure.savefig(fname, dpi=400)
#plt.show()
My output is 5 figures with 12 subplots (one for each month). Hopefully this works for you (and is what you were looking for).
The logic behind this is that you want a figure for each site, and a subplot for each month within the figure. As you have written, you are effectively writing "a subplot for each month, and in the subplot, a bar for each site," which is the opposite of what I think you want (from your question) and why you have just one figure.