3

With the code below, I have produced a figure which I would like to save it in pdf. I use savefig command:

fig.savefig("Surface_I.pdf" )

The pdf file contains a lot of white space in left, and up:

enter image description here

fig.savefig("Surface_I.pdf", bbox_inches='tight') solution cuts out a bit of x and z information, without removing too much space from left and top:

enter image description here

The fig.savefig("Surface_I.pdf", bbox_inches='tight', pad_inches=0.3) solution adds some space, fixing the info just removed:

enter image description here

but there is still too much space in left and top.

How could I remove, or trim, all this left and top white space from the pdf?

Note: all these pictures are a screenshot of the pdf generated.

Code:

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

# Function:
z_fit = a0 + a1*yy + a2*xx + a3*yy**2 + a4*xx**2  + a5*xx*yy

# Parameters:
a0 =  -941.487789948
a1 =  0.0146881652963
a2 =  -2.53533353374e-05
a3 =  -9.64343252786e-05
a4 =  -2.47416662598e-08
a5 =  3.77136886946e-07

x_mesh = np.linspace(10.0000000000000, 2000.0000000000000, 20)
y_mesh = np.linspace(-4.4119598462100, 10.8557347078000, 20)

xx, yy = np.meshgrid(x_mesh, y_mesh)


# Plot the function
fig = plt.figure()
ax = fig.gca(projection='3d')

ax.plot_surface(xx, yy, z_fit, color='b', alpha=0.5)

ax.set_xlabel('\nx')
ax.set_ylabel('y')
ax.set_zlabel('\nzzzzz zzz', linespacing=3)
ax.set_title('\n\nSurface I', linespacing=3)
xlabels=[0, 250, 500, 750, 1000, 1250, 1500, 1750, 2000]
ax.set_xticklabels(xlabels,rotation=90,
                  verticalalignment='baseline',#)#,
                  horizontalalignment='left')

ylabels = [-4, -2, 0, 2, 4, 6, 8, 10]
ax.set_yticklabels(ylabels,rotation=0,
                  verticalalignment='baseline')#,
#                 horizontalalignment='left')


fig.savefig("Surface_I.pdf", bbox_inches='tight', pad_inches=0.3)
DavidC.
  • 669
  • 8
  • 26
  • 1
    I think what you want is to set your own bounding box as shown in the answer by tom in [this question](https://stackoverflow.com/questions/41225293/remove-white-spaces-in-axes3d-matplotlib). Possibly it's even enough to adjust the subplot parameters like in [this question](https://stackoverflow.com/questions/38604100/matplotlib-3d-plot-how-to-get-rid-of-the-excessive-white-space?noredirect=1&lq=1) – ImportanceOfBeingErnest Jul 28 '17 at 19:02

2 Answers2

1

I cropped the resulting pdf plot manually like this:

pdfcrop --margins '0 0 0 0' input.pdf output.pdf

From pdfcrop help message:

--margins "<left> <top> <right> <bottom>"

If you need to crop many plots you can write a simple bash script to automate the process. This whole solution is a bit ugly but it works.

JenyaKh
  • 2,040
  • 17
  • 25
0

Try to change the list border in the code below (border = [xmin,ymin,xmax,ymax] in numerical device coordinates ) It's a bit tricky you create an axis ax0 of size border list and inside you add the axis for the 3d figure. try with border = [-0.5,0,1.5,1] you'll understand the role of this list

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

# Parameters:
a0 =  -941.487789948
a1 =  0.0146881652963
a2 =  -2.53533353374e-05
a3 =  -9.64343252786e-05
a4 =  -2.47416662598e-08
a5 =  3.77136886946e-07

x_mesh = np.linspace(10.0000000000000, 2000.0000000000000, 20)
y_mesh = np.linspace(-4.4119598462100, 10.8557347078000, 20)

xx, yy = np.meshgrid(x_mesh, y_mesh)

# Function:
z_fit = a0 + a1*yy + a2*xx + a3*yy**2 + a4*xx**2  + a5*xx*yy


def axesborder(border):
    # border  = [xmin,ymin,xmax,ymax] 
    # return [xmin,ymin,dx,dy]
    return [border[0],border[1],border[2]-border[0],border[3]-border[1]]

# Plot the function
fig = plt.figure(1)
fig.set_size_inches((16,9), forward=True)
border = [-0.1,0,1.05,1]
#border = [0,0,1,1]
ax0 = fig.add_axes(axesborder(border))
ax0.set_axis_off()

ax = fig.add_axes(ax0.get_position(),projection='3d',zorder = 1)

ax.plot_surface(xx, yy, z_fit, color='b', alpha=0.5)

ax.set_xlabel('\nx')
ax.set_ylabel('y')
ax.set_zlabel('\nzzzzz zzz', linespacing=3)
ax.set_title('\n\nSurface I', linespacing=3)
xlabels=[0, 250, 500, 750, 1000, 1250, 1500, 1750, 2000]
ax.set_xticklabels(xlabels,rotation=90,
                  verticalalignment='baseline',#)#,
                  horizontalalignment='left')

ylabels = [-4, -2, 0, 2, 4, 6, 8, 10]
ax.set_yticklabels(ylabels,rotation=0,verticalalignment='baseline')

plt.show()

plt.savefig('test.pdf')
romain.bqt4
  • 159
  • 1
  • 6