使用嵌套 for 循环的 Matplotlib 子图

Matplotlib subplot using nested for loop

第一次发帖,如有错误敬请见谅

我正在尝试为嵌套的 for 循环创建 matplotlib 子图。

我的数据是广告数据关键字、点击次数、出价、day_of_week列

我想为每个关键字创建 8 个图,其中 x = 出价,y = 点击次数。 我希望第一个图对该关键字进行出价和点击,而其他 7 个图对一周中的每一天进行出价和点击(一周中每天一个图)

现在,我能够将第一个图放到子图网格上(格式看起来很奇怪),其他 7 个图单独出现,而不是显示在子图中。我创建了一个假的 df 并包含了我在下面使用的代码。

我想做的事情:

  1. 要修复的第一个图的格式
  2. 我希望星期一的情节在第二个子情节中

我将不胜感激所有提示。谢谢!

image of my data

My current output

我的代码:

#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)

你的数据是我随机生成的,你可以忽略这个:

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

我稍微修改了你的代码。基本上,如果你正在处理子图,你应该使用 axes[row, col] 而不是 plt 来访问它们,我修改了你的 ndict 以匹配从零开始的索引(0 是你的 'general'情节):

#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)