1

I am producing 12 individual plots using fairly complex functions (e.g. zipping, annotating etc.) and the only way I can save them individually is by writing an IF statement for each graph based on it's y-axis label (the only unique identifier for each graph). This method is really silly but I cannot figure out how to return the plots to a unique name and then save them under that name. I want them saved all individually under a different name (into the same folder) so I have 12 separate plots saved externally. My function for plotting is shown below:

def PlotFromSelectedOutputs(df_3, pH_array, y_var, constants_dict_array):
    fig = plt.figure()
    ax = fig.add_axes([0,0,1,1])
    
    marker_dict = {'Ter':'d', 'Gos':'s', 'MS':'o'}
    color_dict = {'Ter':'b', 'Gos':'g', 'MS':'y'}
    markers = [marker_dict.get(key) for key in df_3.Lithology]
    colors = [color_dict.get(key) for key in df_3.Lithology]
    for _m, _c, _x, _y, _l in zip(markers, colors, df_3.pH, df_3[y_var], df_3.Lithology):
      ax.scatter(_x, _y, marker=_m, color=_c, linewidths = 1, label=_l)
      plt.xlabel("pH")
      plt.ylabel(y_var)
      
    legend_without_duplicate_labels(ax)
      
    plt.xlim([0, 14])
    plt.rcParams['figure.dpi'] = 300
    plt.rcParams.update({'figure.max_open_warning': 0})
    
    for constants_dict in constants_dict_array:
      _ = plt.plot(pH_array, constants_dict['sol'](np.array(pH_array)), 
                   constants_dict['style'], color=constants_dict['color'], label=constants_dict['label'])
      _ = plt.annotate(constants_dict['label'], xy=constants_dict['xy'], xytext=constants_dict['xytext'],
                       color=constants_dict['color'], arrowprops=dict(color=constants_dict['color'], arrowstyle='->'))

# Save figures to "Graphs" folder. ## THIS NEEDS TO BE IMPROVED ##
if y_var == "Log Activity of $Hg^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Hg2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Fe^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Fe2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Fe^{3+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Fe3p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Al^{3+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Al3p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Cu^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Cu2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Cd^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Cd2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Ni^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Ni2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Pb^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Pb2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Zn^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Zn2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $Mn^{2+}$ (mol/L)":
    plt.savefig('Graphs\\' + "Mn2p.png", bbox_inches ="tight")
if y_var == "Log Activity of $H_{2}AsO_{3}^{-}$ (mol/L)":
    plt.savefig('Graphs\\' + "As3p.png", bbox_inches ="tight")
if y_var == "Log Activity of $H_{2}AsO_{4}^{-}$ (mol/L)":
    plt.savefig('Graphs\\' + "As5p.png", bbox_inches ="tight")

I wanted to include the majority of the function in case other aspects of the function will prevent certain methods from working. Thank you!

Olivia
  • 11
  • 2
  • Can you show the part where you loop through the plots and save them? I imagine saving them in a dictionary of `{plot_name: plot_object}` would be the way to go here – Josh Friedlander Sep 14 '22 at 11:01
  • Matti Pastells anwer on [Get the list of figures in matplotlib](https://stackoverflow.com/a/15900439) should help you. – MagnusO_O Sep 14 '22 at 11:03
  • @JoshFriedlander I haven't looped through the plots, this is partly my problem. I'm not clear how to loop through them! I have added the method I have currently used to save them...but it's pretty embarrassing how terrible it is :) – Olivia Sep 14 '22 at 11:19
  • @MagnusO_O Ah yesss this has done it! Any idea how I can use the figlabels instead of fignums function? Can't seem to get that to work. – Olivia Sep 14 '22 at 11:40
  • @Olivia your code posted here isn't running on its own because some other data is missing (at least `y_var`). To enable others to help you it's best to create a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example), so in your case it should work on its own (incl. all variables, dicts, ... being called) but also reduce the numer of different plots (2-3 should be enough for testing a loop). You may also include what you already managed to get going with the `plt.get_fignums()`. Note you can just use e.g. `plt.plot(range(5), range(5))` to mimic data. – MagnusO_O Sep 14 '22 at 12:28
  • @MagnusO_O ahhh right sorry, that does make sense! I have got it to work using the fignums() so I won't waste time now making it reproducible but will bare that in mind for next time I post! – Olivia Sep 14 '22 at 12:36

0 Answers0