Home > Net >  Save plot from matplotlib so that plot is centered
Save plot from matplotlib so that plot is centered

Time:02-15

I am trying to make a plot in python using matplotlib. Specifically, I am using contourf(Xm,Ym,Zm) with colorbar and saving the plot using figX.savefig('name'), with Xm,Ym,Zm being some meshgrids.

The problem: with the colorbar next to the actual plot, the plot is off-center using default parameters in savefig.

The question: How can I produce a figure so that the resulting image file is centered on the center of the actual plot. Best case scenario; the size adjusts so that colorbars and such wont be cut off.

I cant seem to find anything I can use in the parameters of savefig(), and simply have no idea how to go about this.

Some code:

import matplotlib.pyplot as plt
import numpy as np

# make data
Xm, Ym = np.meshgrid(np.linspace(-3, 3, 256), np.linspace(-3, 3, 256))
Zm = (1 - Xm/2   Xm**5   Ym**3) * np.exp(-Xm**2 - Ym**2)
levels = np.linspace(Zm.min(), Zm.max(), 7)

# plot
fig, ax = plt.subplots()

cp = ax.contourf(Xm, Ym, Zm, levels=levels)

cbar = fig.colorbar(cp)

#plt.show()

fig.savefig('plots/contour-plot.png')

The red cross should be equal to the purple cross: enter image description here

CodePudding user response:

As said in the comments, you can use enter image description here

Update As you now introduced the problem of different figure sizes: The same logic can be applied to the height of the colorbar by creating a subGridSpec. If we want to ensure consistency in appearance for different figure size ratios, we have to take this into account while creating the GridSpecs.

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec, GridSpecFromSubplotSpec

#generate data
import numpy as np
Xm, Ym = np.meshgrid(np.linspace(-3, 3, 256), np.linspace(-3, 3, 256))
Zm = (1 - Xm/2   Xm**5   Ym**3) * np.exp(-Xm**2 - Ym**2)
levels = np.linspace(Zm.min(), Zm.max(), 7)

width = 20
height = 8
fig = plt.figure(figsize=(width, height))
#define subplot width ratios 
gs_main = GridSpec(1, 3, width_ratios=[1, 2*width, 1], wspace=1/width)

#add middle plot for contour
plt_ax = fig.add_subplot(gs_main[1])
cp = plt_ax.contourf(Xm, Ym, Zm, levels=levels)

#add colorbar to middle subGridSpec on the right
gs_cbar = GridSpecFromSubplotSpec(3, 1, subplot_spec=gs_main[2], height_ratios=[1, 8, 1])
cbar_ax = fig.add_subplot(gs_cbar[1])
cbar = fig.colorbar(cp, cax=cbar_ax)

#fig.savefig('test.png')

plt.show()

This keeps the width of the colorbar, its distance from the main plot, and its relative height constant over a range of figure sizes.

  • Related