1

I would like to create fig, ax objects outside of a function, then modify the ax from within the function. This approach works fine when my function is a typical python function, but fails when the function is decorated with the @interact or is wrapped by interact from ipywidgets. I'm curious why the wrapping with interact affects ability to pass ax through.

from ipywidgets import interact
from matplotlib import pyplot as plt
import numpy as np

fig, ax = plt.subplots(1)
def mod_ax(n=10):
    x,y = np.random.rand(n), np.random.rand(n)
    ax.scatter(x,y)
    return

# The interact wrapped function will not modify ax
interact(mod_ax, n=20)
# However, the below line works fine to modify ax; 
# comment out the interact line and comment in below line to see modified plot
# mod_ax(n=50)
plt.show()

When you use the interact wrapped function, it doesn't modify ax. I've tried passing the ax around as an argument, but still no luck. It works if you create fig, ax inside of the wrapped function, or just use plt.plot instead of ax.plot, but I want to be able to create the fig, ax outside of the wrapped function and then only modify the content inside to speed up the render time on changes to the interact slider. Any advice would be appreciated.

Sam Jett
  • 710
  • 1
  • 6
  • 15
  • Does the below answer work for you? Any feedback? – Sheldore Jun 14 '19 at 17:33
  • Thank you for the help and the excellent code, but the matplotlib notebook backend did not work for me as I was using Jupyter Lab and it threw a "Javascript error: IPython not found". It did work if i ran jupter notebook instead, but then the previous drawing was not deleted and the new points simply overlapped when the slider was changed (not desired). I think it will be okay for my purpose to just create the fig, ax inside the function, as thats not a costly operation. Else, I can use `ax = plt.gca()` inside the interactive function then plot on those axes. Thank you though! – Sam Jett Jun 15 '19 at 03:43

1 Answers1

0

I am using JuPyter notebook. Your code didn't work for me when I use %matplotlib inline but it works with the %matplotlib notebook backend with the following two changes (highlighted by a comment #). A similar question has been asked here before

%matplotlib notebook # <--- Change 1
from ipywidgets import interact
from matplotlib import pyplot as plt
import numpy as np

fig, ax = plt.subplots(1)
def mod_ax(n=10):
    x,y = np.random.rand(n), np.random.rand(n)
    ax.scatter(x,y)
    fig.canvas.draw() # <--- Change 1
    return 

interact(mod_ax, n=20)
Sheldore
  • 37,862
  • 7
  • 57
  • 71