0

How can I make a ipywidget button in a Jupyter notebook update a plot in a specific axis?

I already know how to make a button update a plot when using a single axis, like so:

import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np

btn = widgets.Button(description='Click')
display(btn)

output = widgets.Output()

def on_click_fn(obj):
    output.clear_output()
    values = np.random.rand(10)
    with output:
        plt.plot(values)
        plt.show()

btn.on_click(on_click_fn)
display(output)

In this example, clicking the button updates the plot and shows a new set of 10 random points. I thought it would be simple to extend this to updating a specific axis, and attempted the following:

import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np

btn = widgets.Button(description='Click')
display(btn)

output = widgets.Output()
fig, ax = plt.subplots(ncols=2)

def on_click_fn(obj):
    output.clear_output()
    values = np.random.rand(10)
    with output:
        ax[0].plot(values)
        plt.show()

btn.on_click(on_click_fn)
display(output)

However, clicking the button in this example does not seem to do anything. I tried different combinations of adding/removing the plt.show() call, using fig.draw() instead, using fig.canvas.draw_idle(), etc, without much success. What's the correct, least "hacky" way of accomplishing this?


Note: This question is only about how to make a button update a plot, like my first example, instead of making the button update a specific axis only.

JLagana
  • 1,224
  • 4
  • 14
  • 33
  • I don't get the problem. The second code works just fine with or without ``plt.show()``. The first code is missing ``fig, ax = plt.subplots()``, but also working just fine. Is it not the output that you are trying to achieve? – Karina Jul 28 '21 at 12:29
  • In my machine the second code does not work. It produces two subplots, but clicking the button does not update one of them to show new random numbers. Did you try running the second code as is and it worked in your machine? – JLagana Jul 28 '21 at 12:32
  • It works for me, as I can't attach any image in comment, I'll put it as an answer, I'll delete it afterwards (since it is not an answer). – Karina Jul 28 '21 at 12:47

1 Answers1

2

with this code

import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
%matplotlib widget

btn = widgets.Button(description='Click')
display(btn)

output = widgets.Output()
fig, ax = plt.subplots(ncols=2)

def on_click_fn(obj):
    output.clear_output()
    values = np.random.rand(10)
    with output:
        ax[0].plot(values)
        plt.show()

btn.on_click(on_click_fn)
display(output)

I got this output

enter image description here

Karina
  • 1,252
  • 2
  • 5
  • 16
  • Interesting. And where's the button? If you click it, does it update the axis on the left and show new numbers? Also, why are there four lines in the plot, instead of a single one? Is that the output after pressing the button a couple of times? – JLagana Jul 28 '21 at 12:53
  • I think I understand the problem. is the import that you listed in the code above the complete import that you have? you need ``%matplotlib widget`` as well for the interactive part in jupyter (or am I actually going further away from your actual problem?) – Karina Jul 28 '21 at 12:55
  • the button is right above the plot, I cropped the screenshot, and yes, I clicked it 4 times to make sure that it works ;) – Karina Jul 28 '21 at 12:56
  • Ah, Karina. I think we understand each other now! No, I did not have a %matplotlib widget in my code. I'll try adding it and will get back with the answer. – JLagana Jul 28 '21 at 13:45
  • Yes, adding `%matplotlib widget` (and installing the package) indeed solved the problem. Maybe you can edit your answer to include that, and I'll mark it as correct? :) – JLagana Jul 28 '21 at 13:52
  • nice! I edited my answer ;) installing the package is indeed a pain, but you managed to do it so fast! I was going to give you this link: https://stackoverflow.com/questions/50149562/jupyterlab-interactive-plot – Karina Jul 28 '21 at 13:54
  • For me it was as simple as `pip install ipympl`. Lucky me, I guess. – JLagana Jul 28 '21 at 15:09