It's nice to plot the graph of the function in jupyter notebook with matplotlib, but it's annoying to change the value and press Ctrl + Enter every time you try and error. It's commonplace to want to dynamically reflect value changes in results with the reactive (old?)-Like trend that is popular these days. When I searched for it, it seems that a library called ipywidgets was developed for jupyter notebook, so I decided to use it.
https://github.com/ipython/ipywidgets
It also seems to allow interactive behavior through UI components such as so-called sliders and text boxes.
I tried it in the following environment.
First, build a virtual environment with venv. If you are a virtualenv person or a bash person, please read as appropriate.
$ python3 -m venv ipywidgets_env
$ source ipywidgets_env/bin/activate.fish #For fish
Install jupyter normally.
(ipywidgets_env) $ pip install jupyter
Lightly confirm that ipywidgets came in together as a dependency.
If you don't have it, you can just put it in with pip install
.
(ipywidgets_env) $ pip list | grep ipywidgets
ipywidgets (5.2.2)
In addition, execute the following command for jupyter to enable the drawing extension function.
(ipywidgets_env) $ jupyter nbextension enable --py widgetsnbextension --sys-prefix
Now that the environment is ready to try ipywidgets, I will try it on jupyter notebook immediately.
(ipywidgets_env) $ jupyter notebook
After starting, create a new notebook in the opened browser and write a function that returns the calculation result ʻa * x + b` in a new cell.
def f(x, a, b):
return a * x + b
To operate the parameters in this function with the UI component of the slider, change the range of the above function f
and the parameters x
, ʻa,
b to the ʻinteract
function as shown below. I'll give it to you.
from ipywidgets import interact
interact(f, x=(-10,10, 1), a=(-10,10, 1), b=(-10,10, 1))
The execution result on the browser is as follows.
A slider appeared on the screen. Play around with the knobs.
Initially x = 0, a = 0, b = 0
and the result was 0
, but if you set x = 10, a = 4, b = -10
, it will be immediately reflected in the result as 30
. Is displayed.
In this way, we were able to confirm the dynamic reflection of the value by ipywigdets.
As a small application, I would like to try to reflect the threshold value of binarization, which is a standard image processing, in the result while operating it by myself. I use my own icon image.
For the time being, I will use Pillow, an image processing tool in Python. If you have already installed it, you do not need to execute the following command.
(ipywidgets_env) $ pip install Pillow
First, import Pillow and load the grayscale 255 gradation image into the global variable ʻimg`.
from PIL import Image
img = Image.open('picture.jpeg').convert('L')
@interact
def binarize(th: (0, 255, 1)):
return img.point(lambda p: 255 if p > th else 0)
You can also use ipywidgets by defining a function binarize
that is dynamically operated by ipywidgets, creating a function that returns the binarized image by the threshold variable th
, and adding a ʻinteract` decorator. can.
When you execute the above cell,
In this way, you can dynamically binarize while moving the threshold slider on the jupyter notebook.
Now that I know how to use the slider, I'll try to imitate the famous GitHub image difference confirmation method. I wasn't very familiar with Pillow yet and didn't know how to adjust the saturation of a partial image, so I ended up doing it in vain way of overlaying the image on top of it.
orig = Image.open('picture.jpeg')
@interact
def github_diff(percentage: (0, 100, 1)):
orig_copied = orig.copy()
box = (int(img.width / 100 * percentage), 0, img.width, img.height)
img_cropped = img.crop(box)
orig_copied.paste(img_cropped, box)
return orig_copied
After loading the original image into ʻorig, the original image is dynamically displayed on the left side and the grayscale image is drawn on the right side based on the ratio specified by the slider.
paste` seems to be a destructive method, taking a copy of the original image for each value change.
I would like to know if there is a better way.
The jupyter notebook, which is already suitable for experiments and verifications, will be even easier to use!
Recommended Posts