PhilippVerpoort
PhilippVerpoort

Reputation: 97

Rasterization of Poly3DCollection in Matplotlib

When trying to enforce rasterization of a Poly3DCollection object in Matplotlib, I get the following error message (and I can confirm no rasterization is applied):

/usr/lib/python3/dist-packages/matplotlib/artist.py:788: UserWarning: Rasterization of '<mpl_toolkits.mplot3d.art3d.Poly3DCollection object at 0x2b49e8faeba8>' will be ignored
  warnings.warn("Rasterization of '%s' will be ignored" % self)

It is possible to rasterize the entire figure, but it is obviously preferable to only rasterize some objects, while keeping items like axes, labels, key, text, etc. as vector graphics.

I have tried using the following syntax in my code:

According to this post, it is possible to rasterize a PolyCollection (without the 3D bit) object.

Any suggestions?

Here is an MWE:

from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.set_xlim([0, 4])
ax.set_ylim([0, 4])
ax.set_zlim([0, 4])

polygons = [[(3, 1, 1), (1, 3, 1), (1, 1, 3)]]

ax.add_collection3d(Poly3DCollection(polygons, facecolors='r', rasterized=True), zs='z')

plt.show()

Upvotes: 4

Views: 1006

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339120

First note that rasterization is only useful for exporting in a vector graphics, like pdf. I am assuming that this is what you are talking about here, so I suppose you would call something like plt.savefig("some.pdf") at the end.

I think someone just forgot to allow rasterizations for 3D objects.

A fix would be to go into the matplotlib source code, locate

python\lib\site-packages\mpl_toolkits\mplot3d\art3d.py

In the imports section add

from matplotlib.artist import allow_rasterization

and further down inside Poly3DCollection find its draw method (In my case it's at line 709) and add @allow_rasterization. It should then look like

@allow_rasterization
def draw(self, renderer):
    return Collection.draw(self, renderer)

If then running the above code, plus saving it to pdf, the triangle is rasterized. Screenshot of pdf:

enter image description here

Upvotes: 3

Related Questions