FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Cannot use interact with matplotlib figures that are updated in-place · Issue #7520 · ipython/ipython · GitHub

Repository navigation

Cannot use interact with matplotlib figures that are updated in-place #7520

Open

Description

In all the examples I can find using interact to produce matplotlib plots in the notebook, the function that is passed to interact generates a new matplotlib Figure. For instance,

http://nbviewer.ipython.org/github/dsoto/ipython/blob/master/examples/Interactive%20Widgets/Image%20Browser.ipynb

If one modifies that example to create a single Figure and Axes beforehand and then just modify what is on the axes for each widget value, it doesn't work; only the widget appears, with no plot. Here is the modification I'm referring to:

%matplotlib inline
import matplotlib.pyplot as plt
from IPython.html.widgets import interact
from sklearn import datasets
digits = datasets.load_digits()
fig = plt.figure()
ax = fig.add_subplot(111)

def browse_images(digits):
    n = len(digits.images)
    def view_image(i):
        ax.imshow(digits.images[i], cmap=plt.cm.gray_r, interpolation='nearest')
        ax.set_title('Training: %s' % digits.target[i])
        plt.show()
        return fig
    interact(view_image, i=(0,n-1))
browse_images(digits)

It often makes more sense to generate the figure and axes beforehand, and modify things in-place. I would like to be able to do this within interact.

Activity

  1. ketch commented on Jan 21, 2015

    Author

    Note that matplotlib's funcanimation does work with in-place figure updates.

  2. jenshnielsen commented on Jan 21, 2015

    Contributor

    I think this is because the inline backend defaults to closing the figure at the end of the cell.
    I think there is a configure option to change this somewhere in IPython

    You can also try using the nnagg backend which is fully interactive and more suitable for interactive work.
    I was experimenting with this recently and it does work. But I found that I had to create the figure in a cell before using interact in the next. I have not had the time to debug that.

    An example is available here http://nbviewer.ipython.org/github/jenshnielsen/netcdf-lesson/blob/master/Interactive%20plotting%20with%20nbagg.ipynb

    Edit For this to work directly I think you need dev versions of both matplotlib and IPython

  3. ketch commented on Jan 21, 2015

    Author

    Thanks for the suggestions.

    I think this is because the inline backend defaults to closing the figure at the end of the cell.

    No, if you create a figure in one cell and reference it later, it appears again just fine. I often use this.

    You can also try using the nnagg backend which is fully interactive and more suitable for interactive work. I was experimenting with this recently and it does work. But I found that I had to create the figure in a cell before using interact in the next. I have not had the time to debug that.

    I tried running your notebook and I get no plot from the last cell:

    I'm running IPython 2.3.1.

    Thanks again for your help; I would really like to make this work.

  4. jenshnielsen commented on Jan 21, 2015

    Contributor

    In that notebook the plot should be attached to the cell above the interact. The idea is first to create a figure and then attach a interact to it in the next cell. If that doesn't work I guess that the nbagg backend is not working for you.

  5. ketch commented on Jan 21, 2015

    Author

    Ah, it does work! I did not expect the widget to control a plot in another output cell, so I didn't notice. Thanks; I will try this.

  6. ketch commented on Jan 21, 2015

    Author

    Thanks to @jenshnielsen for the workaround, which works for me now. It would be nice if one did not need to put the figure creation and interact in separate cells, but does what I wanted. To summarize, what does NOT work is:

    • in-place updates of interact plots using the inline backend
    • in-place updates of interact plots using the nbagg backend, unless the figure creation and interact are in two separate cells.
  7. modified the milestone: wishlist on Feb 12, 2015
  8. davidcortesortuno commented on Dec 23, 2015

    Has this been solved to allow the widget to be in the same place than the plot?

  9. blink1073 commented on Dec 27, 2015

    @davidcortesortuno, the new matplotlib IPython widget will allow that to take place: matplotlib/matplotlib#5754 (comment).

  10. diego898 commented on Aug 9, 2016

    @blink1073 Hello! Im sorry, but how exactly can we get it working now?

    If I define the following function:

    def my_func(x,y,a=1,b=1):
        val = np.sin(a*x**2 + b*y**2)
        return val
    

    I then to try to only plot the particular slices interactively as:

    # Make 3D Plot:
    
    # setup the 3D Grid of points
    x = np.arange(-3, 3, 0.025)              # points in the x axis
    y = np.arange(-3, 3, 0.025)              # points in the y axis
    XGrid, YGrid = np.meshgrid(x, y)                # create the "base grid"
    
    # calculate your function on this grid
    Z = my_func(XGrid,YGrid)
    
    # setup 3D figure
    fig = plt.figure(figsize=(20,5));
    # Create 3D Subplot
    ax1 = fig.add_subplot(1, 2, 1, projection='3d')
    # plot it on the sublot
    ax2 = fig.add_subplot(2,2,2)
    # plot it on the sublot
    ax3 = fig.add_subplot(2,2,4)       
    
    # 3D Plot
    ax1.plot_surface(XGrid, YGrid, Z,     # data values (2D Arryas)
                   rstride=2,           # row step size
                   cstride=2,           # column step size
                   cmap=cm.RdPu,       # colour map
                   linewidth=0,         # wireframe line width
                   antialiased=True,
                   alpha=0.3);
    
    # interactive plotting
    def plot_slices(x_val, y_val,ax2,ax3):
        ## plot x slice
    
        # setup y value
        y = np.arange(-3,3,0.025)
    
        # calculate function for that x_value
        z = my_func(x_val,y)
    
        ax2.plot(y,z, 'r--');
    
        # setup figure asthetics
        ax2.set_xlabel('y axis');
        ax2.set_ylabel('z axis');
        ax2.set_title('A slice in x: f(' + str(np.round(x_val,2)) + ', y)');
    
        ## plot y slice
    
        # setup x values
        x = np.arange(-3,3,0.025)
    
        # calculate function for that y_value
        z = my_func(x,y_val)
    
        # plot it on the sublot
        ax3.plot(x,z, 'b--');
    
        # setup figure asthetics
        ax3.set_xlabel('y axis');
        ax3.set_ylabel('z axis');
        ax3.set_title('A slice in y: f(x,' + str(np.round(y_val,2)) + ')');
    
    
    interact(plot_slices, x_val=(-3,3,0.1), y_val=(-3,3,0.1),ax2=fixed(ax2),ax3=fixed(ax3));
    

    But that doesn't work. I get an initial plot and then upon moving the sliders the entire figure disappears. The only way to make it work is to have it declare the figure and axes inside the function everytime!

  11. blink1073 commented on Aug 9, 2016

    The widget will be in matplotlib 2.1, which has not yet been released.

  12. diego898 commented on Aug 9, 2016

    ah. Ok thanks @blink1073 !

  13. satra commented on Sep 8, 2017

    Contributor

    i'm testing with matplotlib 2.1.0rc1 and this bug appears to be still there.

  14. satra commented on Sep 8, 2017

    Contributor

    actually it seems that it is working.

  15. jenshnielsen commented on Sep 9, 2017

    Contributor

    The widget vas removed from matplotlib 2.1 after @blink1073 comment. It's now what will become https://github.com/matplotlib/jupyter-matplotlib

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL