first time poster so apologize in advance for mistakes.
I'm trying to create a matplotlib subplots for a nested for loop.
My data is advertisement data keyword, clicks, bid, day_of_week columns
I want to create 8 plots for each keyword, with x = bids and y = clicks. I would like the first plot to have bids and clicks for that keyword, and 7 others to have bids and clicks for each day of the week (one plot per day of the week)
Right now, I'm able to get the first plot onto the subplot grid (with the formatting looking weird) and the other 7 plots are appearing on their own instead of showing in the subplots. I created a fake df and included the code I'm using below.
What I would like to do:
I would appreciate any and all tips. Thank you!
My code:
#creating a unique list of days for the
day_list = df['day_of_week'].unique()
#create a plot for each keyword by day of week
def keyword_plots(x, y):
#create dict so that each day has a spot on the figure subplot
ndict = {'Monday': 2,
'Tuesday': 3,
'Wednesday': 4,
'Thursday': 5,
'Friday': 6,
'Saturday' : 7,
'Sunday' :8}
#dealing with colors
color_labels = y['day_of_week'].unique()
rgb_values = sns.color_palette("husl", 7)
color_map = dict(zip(color_labels, rgb_values))
#loop through each keyword and add it to the plot (first spot)
for each in x:
#create subset for each keyword
subset = y[y["keyword"]==each][["clicks","bid", "day_of_week"]]
#create one figure per keyword with 8 spaces
fig, axes = plt.subplots(2, 4, figsize=(20, 8))
fig.tight_layout()
#add this keyword plot to the first subplot space
ax=fig.add_subplot(4,4,1)
plt.scatter(subset['bid'], subset['clicks'], c = subset['day_of_week'].map(color_map), alpha=0.5)
#labels
plt.title(each)
plt.xlabel("bid")
plt.ylabel("clicks")
#trendlines
z = np.polyfit(subset["bid"], subset['clicks'], 1)
p = np.poly1d(z)
pylab.plot(subset['bid'],p(subset['bid']),"r--")
plt.show()
#loop through each day of the week and create one plot per week per keyword (7 total for Mon-Sun)
for i in day_list:
#subset the data
day_sub = subset[subset["day_of_week"]==i][["clicks","bid", "day_of_week"]]
#add the plot to the space corresponding to day of week (in ndict)
ax=fig.add_subplot(4, 4, ndict[i])
#create plot
plt.scatter(day_sub['bid'], day_sub['clicks'], c = day_sub['day_of_week'].map(color_map), alpha=0.5)
#plot lables
plt.title(each + " " + i)
plt.xlabel("bid")
plt.ylabel("clicks")
#trendline
z = np.polyfit(day_sub["bid"], day_sub['clicks'], 1)
p = np.poly1d(z)
pylab.plot(day_sub['bid'],p(day_sub['bid']),"r--")
plt.show()
keyword_plots(list_of_keywords_I_want, keywords_df)
I generated your data randomly, you can just ignore this:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from itertools import cycle, islice
size = 40
clicks = np.random.randint(6, size=size)
bids = np.random.rand(size)*6
day_of_week = ['Friday', 'Monday', 'Saturday', 'Sunday', 'Thursday', 'Tuesday', 'Wednesday']
day_of_week = list(islice(cycle(day_of_week), size))
day_of_week.sort()
day_of_week
keywords = ['lobsters']*40
df = pd.DataFrame([keywords, clicks, bids, day_of_week], index=['keyword', 'clicks', 'bid', 'day_of_week']).T
df['clicks'] = df['clicks'].astype(int)
df['bid'] = df['bid'].astype(float)
#creating a unique list of days for the
day_list = df['day_of_week'].unique()
list_of_keywords_I_want = ['lobsters']
keywords_df = df
I modified your code a little bit. Basically if you are working with subplots you should access them with the axes[row, col]
instead of plt
, and I modified your ndict
to match zero-based indexing (with 0 being your 'general' plot):
#create a plot for each keyword by day of week
def keyword_plots(x, y):
#create dict so that each day has a spot on the figure subplot
ndict = {'Monday': 1,
'Tuesday': 2,
'Wednesday': 3,
'Thursday': 4,
'Friday': 5,
'Saturday' : 6,
'Sunday' :7}
#dealing with colors
color_labels = y['day_of_week'].unique()
rgb_values = sns.color_palette("husl", 7)
color_map = dict(zip(color_labels, rgb_values))
#loop through each keyword and add it to the plot (first spot)
for each in x:
#create subset for each keyword
subset = y[y["keyword"]==each][["clicks","bid", "day_of_week"]]
#create one figure per keyword with 8 spaces
fig, axes = plt.subplots(2, 4, figsize=(20, 8))
fig.tight_layout()
axes[0,0].scatter(subset['bid'], subset['clicks'], c = subset['day_of_week'].map(color_map), alpha=0.5)
#labels
axes[0,0].set_title(each)
axes[0,0].set_xlabel("bid")
axes[0,0].set_ylabel("clicks")
#trendlines
z = np.polyfit(subset["bid"], subset['clicks'], 1)
p = np.poly1d(z)
axes[0,0].plot(subset['bid'],p(subset['bid']),"r--")
#loop through each day of the week and create one plot per week per keyword (7 total for Mon-Sun)
for i in day_list:
#subset the data
day_sub = subset[subset["day_of_week"]==i][["clicks","bid", "day_of_week"]]
#create plot
axes[ndict[i] // 4, ndict[i] % 4].scatter(day_sub['bid'], day_sub['clicks'], c = day_sub['day_of_week'].map(color_map), alpha=0.5)
#plot lables
axes[ndict[i] // 4, ndict[i] % 4].set_title(each + " " + i)
axes[ndict[i] // 4, ndict[i] % 4].set_xlabel("bid")
axes[ndict[i] // 4, ndict[i] % 4].set_ylabel("clicks")
#trendline
z = np.polyfit(day_sub["bid"], day_sub['clicks'], 1)
p = np.poly1d(z)
axes[ndict[i] // 4, ndict[i] % 4].plot(day_sub['bid'],p(day_sub['bid']),"r--")
plt.show()
keyword_plots(list_of_keywords_I_want, keywords_df)
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.