Reniel Calzada Reniel Calzada - 2 years ago 111
Python Question

Passing axes as **kwarg in Python

I'm building a wrapper to generate plots in Matplotlib, and I want to be able to optionally specify the axes in which to build the plot.

For example, I have:

def plotContourf(thing, *argv, **kwargs):
return plt.tricontourf(thing[0], thing[1], thing[2], *argv, **kwargs)

def plotScatter(thing, *argv, **kwargs )
return plt.scatter(thing[0], thing[1], *argv, **kwargs)

fig, ((ax0,ax1),(ax2,ax3)) = plt.subplots(2,2)

plotContourf(some_thing, axes=ax0)
plotScatter(some_thing, axes=ax2)


Which runs, but everything gets plotted on the very last axes (ax3) and not in the axes specified via the axes kwargument. (No errors here, it just appears on the wrong axes)

For the curious, the reason I want to do this is so that the user can either set an axes, or for the lazy people, they can just call plotContourf() with no specified axes and still get something that they can plt.show()

On the other hand, I tried

def plotContourf(thing, axes=None, *argv, **kwargs):
if axes is None:
fig, axes = plt.subplots()

return axes.tricontourf(thing[0], thing[1], thing[2], *argv, **kwargs)


But then I get:

TypeError: plotContourf() got multiple values for keyword argument 'axes'

I understand that this error is due to 'axes' already being a keyword argument. I know I can use a different keyword but then what's the use of the axes kwarg?

Thanks!

EDIT:
Full traceback (for second option described above):

Traceback (most recent call last):
File "mods.py", line 51, in <module>
adcirc.plotContourf(hsofs_mesh, -1*hsofs_mesh['depth'], axes=ax0)
TypeError: plotContourf() got multiple values for keyword argument 'axes'


And the actual wrapper:

def plotContourf(grid, axes=None, *argv, **kwargs):
if axes is None:
fig, axes = plt.subplot()
return axes.tricontourf(grid['lon'], grid['lat'], grid['Elements']-1, *argv, **kwargs)

Answer Source

The problem is that you're calling the function with -1*hsofs_mesh['depth'] in place of axes and then adding the axes keyword argument again at the end.

In [10]: def fun(a, x=1, *args, **kwargs):
    ...:     print(x)
    ...:     

In [11]: fun(1, 3, x=4)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-31b5e42fb4be> in <module>()
----> 1 fun(1, 3, x=4)

TypeError: fun() got multiple values for keyword argument 'x'

See in this example it's reading 3 as x and then I'm passing x=4. Causing the error you are experiencing.

A solution would be to add another argument to your function like this:

def plotContourf(thing, other_thing=None, axes=None, *argv, **kwargs):
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download