0

I want to plot a grid of plots. Usually it's around 9-12 plots but currently I just play around with 3.

I'm using this code. It might not be the nicest but then I'm just playing around.

def plot(config):
    # specify grid
    nprops = 3
    ncols = nprops # Number of props you want to plot
    nrows = len(config["number_of_steps"]) # rows

    # plot experiments
    for integration_type in config["integration_types"]:
        for atoms in config["number_of_atoms"]:
            fig = plt.figure()
            #plt.tight_layout()
            #plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.42)
            i = 1
            title = f'{config["title"]} - {atoms} atoms - integration_type={integration_type}'
            fig.suptitle(title)
            for steps in config["number_of_steps"]:
                filename = f"params_{integration_type}_{atoms}_{steps}"

                # Get properties from output file
                props = get_all_properties(f"out/{filename}.out")

                # Plot total Energy
                ax = fig.add_subplot(nrows, ncols, i)
                ax.plot(props["step"], props["etot"], label="Etot")
                plt.title(f"{atoms} atoms, {steps} steps")

                ax.legend()
                ax.set_ylabel('Etot')  
                ax.set_xlabel('Step')
                i += 1

                # Plot kinetic Energy
                ax = fig.add_subplot(nrows, ncols, i)
                ax.plot(props["step"], props["ekin"], label="Ekin")
                plt.title(f"{atoms} atoms, {steps} steps")

                ax.legend()
                ax.set_ylabel('Ekin')  
                ax.set_xlabel('Step')
                i += 1

                # Plot potential Energy
                ax = fig.add_subplot(nrows, ncols, i)
                ax.plot(props["step"], props["epot"], label="Epot")
                plt.title(f"{atoms} atoms, {steps} steps")

                ax.legend()
                ax.set_ylabel('Epot')  
                ax.set_xlabel('Step')
                i += 1
            plt.legend()
            plt.savefig(f"out/params_{integration_type}_{atoms}_{steps}.png", dpi=fig.dpi)
        plt.show()

the show() function shows me this: enter image description here

while the savefig() function shows me this: enter image description here

I'm using 3 in tab mode. So the show() is basically fullscreen on my 13" 2k notebook screen. I know that a wm basically resizes the image but I thought I fix that by passing dpi=fig.dpi to the savefig() functions but as you can see, it doesn't seem to work.

Any idea how I can get it to work properly?

Edit: I wanted to add: If I have 9-12 plots, the labels might overlap even in show() which I fixed with subplot_adjust() which is commented out. If there's a better way to do such a grid, I'm glad to hear about it.

xotix
  • 494
  • 1
  • 13
  • 41
  • `show()` automatically resizes things according to interaction, of course. Have you tried `plt.tight_layout()` before `plt.savefig()` as in https://stackoverflow.com/questions/13073045/matplotlib-savefig-size-control? Otherwise you may need to resize everything manually. – jpf May 13 '20 at 11:38
  • I tried that and while it makes it a little bit better it doesn't solve it. I also told i3 to open it in floating mode (so it doesn't resize it) but now the figures are just very small and thus everything is squeezed. – xotix May 13 '20 at 12:13
  • So, actually my problem was this: There's a default figure size, which is set once you create the figure. (Like the object). Which resulted in my figure being squeezed. So to solve that, just set a figure size. Now, to get the proper size you set when using i3, you have to tell i3 to open the plots (you show using show()) in floating mode. For that, just `add for_window [class="Matplotlib"] floating enable`to your i3config. – xotix May 13 '20 at 12:33

0 Answers0