Home > OS >  saving figure in a loop matplotlib
saving figure in a loop matplotlib

Time:01-15

I'm working on using a for loop to produce graphs for each set of data I have. Each plot prints correctly however the savefig() portion of my code only saves the last plot under each file name.

Here is a section of my code

total = 3
idx_list = []
dct = {}

for i, df in enumerate(graph_list):
    data = pd.DataFrame(df)
    for idx, v in enumerate(data['content'].unique()):
        dct[f'x{idx}'] = data.loc[data['content'] == v]
        idx_list.append(idx)
        xs = dct[f'x{idx}'].Time
        yB = dct[f'x{idx}'].Weight
        yA = dct[f'x{idx}'].Height


        fig, ax = plt.subplots(figsize =(10,8))

        legends = ['Weight', 'Height']

        ax.plot(xs, yB,  linestyle = ':', color ='#4c4c4c', linewidth = 4.0)
        ax.plot(xs, yA, color = '#fac346', linewidth = 3.0)

        ax.legend(legends, loc = 'lower center', ncol = len(legends), bbox_to_anchor = (0.5, -0.15), frameon = False) 
    
        ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals = None, symbol ='%', is_latex = False))

        ax.set_xticks(xs[::4])
        ax.tick_params(axis = 'x', labelrotation = 45, labelsize = 10)

        ax.yaxis.grid()

        new_idx = [x 1 for x in idx_list]

for graph in range(total 1):
    if graph != 0:
       for ids in set(new_idx):
           print('Graph {0} ID {1}'.format(graph, ids))
           fig.savefig('Graph {0} ID {1}.jpg'.format(graph, ids))

I want each graph to save under the file names:

  • Graph 1 ID 1
  • Graph 1 ID 2
  • Graph 2 ID 1
  • Graph 2 ID 2
  • Graph 3 ID 1
  • Graph 3 ID 2

Thanks for any help you can provide!

CodePudding user response:

You do not keep a reference to each figure, so when you call fig.savefig in the final loop you are actually saving the figure referenced by fig (which is the last figure) each time. There are many ways to manage this: you can save the figure in the same loop that created it, you can assign a unique name to each figure, or you can keep a reference to each figure in a list. The first option is simpler:

dct = {}  # I assume this dict is used for something after saving the figures. Otherwise it is not necessary


for i, df in enumerate(graph_list):
    data = pd.DataFrame(df)
    for idx, v in enumerate(data['content'].unique()):
        dct[f'x{idx}'] = data.loc[data['content'] == v]

        xs = dct[f'x{idx}'].Time
        yB = dct[f'x{idx}'].Weight
        yA = dct[f'x{idx}'].Height

        fig, ax = plt.subplots(figsize=(10, 8))

        legends = ['Weight', 'Height']

        ax.plot(xs, yB,  linestyle=':', color='#4c4c4c', linewidth=4.0)
        ax.plot(xs, yA, color='#fac346', linewidth=3.0)

        ax.legend(legends, loc='lower center', ncol=len(legends),
                  bbox_to_anchor=(0.5, -0.15), frameon=False)

        ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1,
                                    decimals=None, symbol='%', is_latex=False))

        ax.set_xticks(xs[::4])
        ax.tick_params(axis='x', labelrotation=45, labelsize=10)

        ax.yaxis.grid()

        print('Graph {0} ID {1}'.format(i 1, idx 1))
        fig.savefig('Graph {0} ID {1}.jpg'.format(i 1, idx 1))
        plt.close(fig)  # if you do not need to leave the figures open
  •  Tags:  
  • Related