Snippet of my code:
…
self.lon2, self.lat2 = np.meshgrid(lon, lat)
…
def data_triangulation_init(self):
elements = (self.grid.elements.data.astype(‘int32’) - 1).T
d = self.model_lon[elements].max(axis=1) - self.model_lon[elements].min(axis=1)
no_cyclic_elem = np.argwhere(d < 100).ravel()
triang = mtri.Triangulation(self.model_lon, self.model_lat, elements[no_cyclic_elem])
tri = triang.get_trifinder()
return tri, triang
When I try to pickle the return value of this function I run into “TypeError: cannot pickle ‘matplotlib._tri.Triangulation’ object”. Can someone please help me?
A Python Triangulation
object contains a C++ object, and in general you cannot pickle C++ objects. To fix this would only be a small change in Matplotlib. In the meantime, there is a workaround which is to delete the C++ object because a new one will be created when it is next needed. For example:
triang = mtri.Triangulation(...)
# Do stuff with triang if required.
del triang._cpp_triangulation
pickle.dumps(triang) # This now works.
Hey ianthomas23. Thank you very much for your reply. I tried doing this, but I got into another error: “cannot pickle ‘matplotlib._tri.TrapezoidMapTriFinder’ object”. I think it is because of “tri = triang.get_trifinder()” since I am trying to pickle both tri and triang, but I am not sure. Do you know any possible solution for this?
A Triangulation
has an optional TriFinder
object which is also implemented in C++, so this is the same situation as before. You could delete the _tri_finder
, or just set is to None
:
triang._tri_finder = None
and you should be able to pickle the triang
.
Even if I do that, the same error persists. If you don’t mind can you please answer this question?
If I set tri_finder to None, can I still pickle “tri = triang.get_trifinder()”. I am asking this because tri takes about 40GB of space in my case, and if I cannot pickle it, I have to repeat that for each day of the year. And it would eat up a huge amount of space.
No, you can never pickle a TriFinder
.