【问题标题】:Matplotlib subplot using nested for loopMatplotlib 子图使用嵌套 for 循环
【发布时间】:2021-08-02 06:52:28
【问题描述】:

第一次发帖,如有错误请提前道歉。

我正在尝试为嵌套的 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)

【问题讨论】:

    标签: python matplotlib visualization nested-loops subplot


    【解决方案1】:

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

    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 是您的“一般”图):

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

    【讨论】:

    • 谢谢!这看起来很棒。你知道如何调整子图之间的间距,使轴不重叠吗?
    • here 所述,tight_layout() 是为标签腾出空间的最简单方法。 herehere 已经提出了相同的问题。所以除此之外,我不知道怎么做,对不起。
    猜你喜欢
    • 2021-12-11
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    相关资源
    最近更新 更多