简体   繁体   中英

Matplotlib widgets don't work properly with IPython

I am using Matplotlib in a class to view 3-Dimensional physical data.

I have a fiew sliders and radiobuttons, in which I can update the view on the data (eg. which layer, or what scale to use). This works perfectly fine in Pycharm when running a script. But when I use IPython in Pycharm, to work dynamically on my data, the widgets are either buggy (one of the sliders) or don't respond at all (all the other widgets). The tools of matplotlib for zooming and panning work totally fine though.

I am not quite sure, how to adress this problem, and what I can do for debugging. I beleave in both cases the backend is PyQt5.

There is one more difference, that might be a hint to a solution: the new opened matplotlib window, doesn't show the matplotlib logo, and is just white when run in Ipython.

Here is the minimal code, that reproduces the error. When run from pycharm, all is fine. When run in Pycharm debugger, aka IPython, the error.

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, RadioButtons

def plot():
    def create_axes():
        ax_slider1 = plt.axes([0.1, 0.1, 0.3, 0.1])
        slider1 = Slider(label="", ax=ax_slider1, valmin=0, valmax=10)

        ax_slider2 = plt.axes([0.1, 0.25, 0.3, 0.1])
        slider2 = Slider(ax=ax_slider2, label="", valmin=0, valmax=10)

        ax_button = plt.axes([0.1, 0.5, 0.15, 0.1])
        button = RadioButtons(ax=ax_button, labels=["a", "b"])

        return slider1, slider2, button

    def update_axes():
        good_slider.ax.set_xlim(1, 2)
        fig.canvas.draw_idle()

    def update_good_slider(offset):
        print(offset)
        update_axes()

    def update_buttons(vlim_type):
        print(vlim_type)
        update_axes()

    def update_bad_slider(factor):
        print(factor)
        update_axes()

    fig, z_ax = plt.subplots()
    fig.subplots_adjust(left=0.5)

    good_slider, bad_slider, buttons = create_axes()

    good_slider.on_changed(update_good_slider)
    buttons.on_clicked(update_buttons)
    bad_slider.on_changed(update_bad_slider)
    plt.show()

plot()

Update I eventually got it working with help from here, and reprogramming my code to be more object orientated, and saving the plot() into a variable (see the commment from @medium-dimensional).

To make Matplotlib interactive in Jupyter Notebook, you need ipympl .

Once installed, you can use %matplotlib widget right after importing all the required package in your script.

Storing the class instance plot() in a variable might help keeping the reference to interactive widget alive.

The following code worked in JupyterLab for me:

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, RadioButtons

%matplotlib widget

def plot():
    def create_axes():
        ax_slider1 = plt.axes([0.1, 0.1, 0.3, 0.1])
        slider1 = Slider(label="", ax=ax_slider1, valmin=0, valmax=10)

        ax_slider2 = plt.axes([0.1, 0.25, 0.3, 0.1])
        slider2 = Slider(ax=ax_slider2, label="", valmin=0, valmax=10)

        ax_button = plt.axes([0.1, 0.5, 0.15, 0.1])
        button = RadioButtons(ax=ax_button, labels=["a", "b"])

        return slider1, slider2, button

    def update_axes():
        good_slider.ax.set_xlim(1, 2)
        fig.canvas.draw_idle()

    def update_good_slider(offset):
        print(offset)
        update_axes()

    def update_buttons(vlim_type):
        print(vlim_type)
        update_axes()

    def update_bad_slider(factor):
        print(factor)
        update_axes()

    fig, z_ax = plt.subplots()
    fig.subplots_adjust(left=0.5)

    good_slider, bad_slider, buttons = create_axes()

    good_slider.on_changed(update_good_slider)
    buttons.on_clicked(update_buttons)
    bad_slider.on_changed(update_bad_slider)
    plt.show()

w = plot()

Jupyter Core packages on my machine:

IPython          : 8.0.1
ipykernel        : 6.9.1
ipywidgets       : 7.6.5
jupyter_client   : 7.1.2
jupyter_core     : 4.9.2
jupyter_server   : 1.13.5
jupyterlab       : 3.2.9
nbclient         : 0.5.11
nbconvert        : 6.4.2
nbformat         : 5.1.3
notebook         : 6.4.8
qtconsole        : not installed
traitlets        : 5.1.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM