简体   繁体   中英

Save Matplotlib figure as TIFF

Does anyone know how to save a Matplotlib figure as *.tiff? It seems that this format is not supported in Python, while the journals are quite often ask for that format.

I am adding some minimal code:

# -*- coding: utf-8 -*-

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

# fig setup
fig = plt.figure(figsize=(5,5), dpi=300)
ax = fig.gca(projection='3d')
ax.set_xlim([-1,1])
ax.set_ylim([-1,1])
ax.set_zlim([-1,1])
ax.axes.xaxis.set_ticklabels([])
ax.axes.yaxis.set_ticklabels([])
ax.axes.zaxis.set_ticklabels([])

# draw a surface
xx, yy = np.meshgrid(range(-1,2), range(-1,2))
zz = np.zeros(shape=(3,3))
ax.plot_surface(xx, yy, zz, color='#c8c8c8', alpha=0.3)
ax.plot_surface(xx, zz, yy, color='#b6b6ff', alpha=0.2)

# draw a point
ax.scatter([0],[0],[0], color='b', s=200)

This works:

fig.savefig('3dPlot.pdf')

But this does not:

fig.savefig('3dPlot.tif')

As a workaround, there would be nothing to stop you using the Python PIL package to save your image in TIFF format:

# -*- coding: utf-8 -*-

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

from PIL import Image
import io

# fig setup
fig = plt.figure(figsize=(5,5), dpi=300)
ax = fig.gca(projection='3d')
ax.set_xlim([-1,1])
ax.set_ylim([-1,1])
ax.set_zlim([-1,1])
ax.axes.xaxis.set_ticklabels([])
ax.axes.yaxis.set_ticklabels([])
ax.axes.zaxis.set_ticklabels([])

# draw a surface
xx, yy = np.meshgrid(range(-1,2), range(-1,2))
zz = np.zeros(shape=(3,3))
ax.plot_surface(xx, yy, zz, color='#c8c8c8', alpha=0.3)
ax.plot_surface(xx, zz, yy, color='#b6b6ff', alpha=0.2)

# draw a point
ax.scatter([0],[0],[0], color='b', s=200)

#fig.savefig('3dPlot.pdf')

# Save the image in memory in PNG format
png1 = io.BytesIO()
fig.savefig(png1, format="png")

# Load this image into PIL
png2 = Image.open(png1)

# Save as TIFF
png2.save("3dPlot.tiff")
png1.close()

If Python 2.x is being used, use cStringIO instead of BytesIO as follows:

import cStringIO

# Replace the BytesIO() call with
png1 = cStringIO.StringIO()

This is great! Thanks ot Martin Evans . However, for those who would like to make it happen in Python3.x , small fixes (since cStringIO module is not available; and I would rather use BytesIO )

# -*- coding: utf-8 -*-

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

from PIL import Image
from io import BytesIO

# fig setup
fig = plt.figure(figsize=(5,5), dpi=300)
ax = fig.gca(projection='3d')
ax.set_xlim([-1,1])
ax.set_ylim([-1,1])
ax.set_zlim([-1,1])
ax.axes.xaxis.set_ticklabels([])
ax.axes.yaxis.set_ticklabels([])
ax.axes.zaxis.set_ticklabels([])

# draw a point
ax.scatter([0],[0],[0], color='b', s=200)

# save figure
# (1) save the image in memory in PNG format
png1 = BytesIO()
fig.savefig(png1, format='png')

# (2) load this image into PIL
png2 = Image.open(png1)

# (3) save as TIFF
png2.save('3dPlot.tiff')
png1.close()

Matplotlib does support tif since version 1.1 but the support is optional and not obvious. As long as you have pillow installed, you can save to tif like you can save to any other format. Thus your example would simply be:

# -*- coding: utf-8 -*-

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
import PIL # not necessary but mustn't fail

# fig setup
fig = plt.figure(figsize=(5,5), dpi=300)
ax = fig.gca(projection='3d')
ax.set_xlim([-1,1])
ax.set_ylim([-1,1])
ax.set_zlim([-1,1])
ax.axes.xaxis.set_ticklabels([])
ax.axes.yaxis.set_ticklabels([])
ax.axes.zaxis.set_ticklabels([])

# draw a surface
xx, yy = np.meshgrid(range(-1,2), range(-1,2))
zz = np.zeros(shape=(3,3))
ax.plot_surface(xx, yy, zz, color='#c8c8c8', alpha=0.3)
ax.plot_surface(xx, zz, yy, color='#b6b6ff', alpha=0.2)

# draw a point
ax.scatter([0],[0],[0], color='b', s=200)

fig.savefig('3dPlot.tif')

All you have to do is install Pillow . Then you can use just this:

fig.savefig('3dPlot.tiff')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM