0

I have an "image" class which exposes a method named ".extent()" and this class is a subclass of numpy.ndarray.

So, I can call

im = image( ( 256, 256 ), extent = ( 0.0, 3.14, -1.0, 1.0 ) )
matplotlib.pyplot.imshow( im, extent = im.extent() )

What I really would like to do is to inject code so that ".imshow()" in order to be able to call simply

matplotlib.pyplot.imshow( im )

and to have ".imshow()" to set the extent automatically.

Writing another function to do so is trivial, but I want to have "matplotlib.pyplot.imshow()" to do it.

So, my question is:

Is it possible to a model, written by me, to inject code inside a function from other module?

If so, how?

4
  • Since imshow is not defined as a protocol (such as the iterator protocol which works by the next function or the descriptor protocol which works through property) then you cannot expect imshow to disassemble objects that are passed to it and to behave different for different types of objects, beyond whatever extent this happens already in the source code of imshow. If "showing" was implemented as an interface, as in say Haskell, then you could just ensure your class implements the interface. But this is not how matplotlib has chosen to work. Commented Oct 9, 2014 at 20:56
  • While you can simply rename things to put a new function in for imshow (as in Joran Beasley's answer) this usually causes more harm than good, especially for people picking up your code and expecting a matplotlib standard function like imshow to work with a certain calling signature and finding that instead it's been monkeypatched with your custom function. In most cases, it's better to just write a new function or have a class method that handles inducing the correct imshow call. Commented Oct 9, 2014 at 20:59
  • @EMS, I don't agree with this latter comment. It is perfectly possible to do something different from the expected only when the argument is of my "image" class. Commented Oct 10, 2014 at 12:55
  • But not by using the existing source code of imshow. It was not implemented that way. It has no hooks for any code injection to make it behave differently (which is what it would have if it was an interface). Of course you can make a new function that first checks whether the argument is of your type, dispatches the right call, or else just calls imshow the regular way. --- making a new function --- Which is something you said you did not want. Commented Oct 10, 2014 at 13:01

1 Answer 1

4
original = matplotlib.pyplot.imshow
matplotlib.pyplot.imshow = lambda x: original(x, extent=x.extent())

is one way to do it I suppose

or even better as suggested in the comments

imshow = lambda x:matplotlib.pyplot.imshow(x,extent=x.extent())

even though it doesnt "inject code"

Sign up to request clarification or add additional context in comments.

1 Comment

Even better would be if the OP could forego the requirement that it has to be matplotlib's imshow that invokes like this, and simply give that lambda a new name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.