In matplotlib
, a common problem are unwanted white lines between Patch
objects drawn with pcolor
, pcolormesh
, and contourf
(see this thread for the former two and this thread for the latter).
I've attempted to fix this automatically by adding new methods to my Axes
class/subclass instances using MethodType
. I do this instead of subclassing simply because I want to generate Axes
by passing slices of GridSpec
objects to the add_subplot
method on a Figure
instance, and I am not aware of how I could do this with some kind of subclassed matplotlib.axes.Subplot
(but I welcome advice). Here is some example code...
from types import MethodType
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
f = plt.figure()
gs = GridSpec(2,1)
ax = f.add_subplot(gs[0,0])
def _pcolormesh(self, *args, **kwargs):
p = self.pcolormesh(*args, **kwargs)
p.set_edgecolor('face')
p.set_linewidth(0.2) # will cover white lines, without making dot in corner of each square visible
return p
def _contourf(self, *args, **kwargs):
c = self.contourf(*args, **kwargs)
for _ in c.collections:
_.set_edgecolor('face')
return c
ax.mypcolormesh = MethodType(_pcolormesh, ax)
ax.mycontourf = MethodType(_contourf, ax)
In the last line, I would prefer to be able to write ax.pcolormesh
instead of ax.mypcolormesh
, but this raises a RecursionError
because _pcolormesh
calls the original method name... which is now aliased to itself.
So, how can I access a method on this Axes
instance, override it, and preserve the original name?
The efficient solution
Since replacing the method for each axes individually is a lot more typing than using a simple function, the most efficient method would be to create a python file
myhacks.py
with the respective functionand use it whenever the improved version of the pcolormesh is needed
This works also well for already created files, where one would simply search an replace
"ax.pcolormesh("
with"m.pcolormesh(ax,"
(if necessary using regex for possible other axes names).The academic solution
It is of course possible to subclass
matplotlib.axes.Axes
to include the desired function. Since there is no real benefit of this, except knowing how to do it, I would call it "academic solution".So, again we can create a file
myhacks.py
for our custom class, register the custom class as a projection to matplotlib,and use this by importing it and creating the axes using the projection:
Well... I solved it, sort of. Just use
which saves a copy of the old method, and then, for example,
which assigns the new method to call the copy of the old method.