Reputation: 603
I want to provide a GUI for the user to easily remove outliers from a dataset and plot the data. Therefore, I provide input fields for the user to specify data value limits; and a button to update the plot:
import pandas as pd
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display, clear_output
df = pd.read_csv("https://raw.githubusercontent.com/juliangermek/aia/main/treasure_data.csv", sep=";")
min_value_x = df["x"].min()
max_value_x = df["x"].max()
min_value_y = df["y"].min()
max_value_y = df["y"].max()
min_x = widgets.BoundedIntText(
value=min_value_x,
min=min_value_x,
max=max_value_x,
step=1,
description='x lower limit:',
)
max_x = widgets.BoundedIntText(
value=max_value_x,
min=min_value_x,
max=max_value_x,
step=1,
description='x upper limit:',
)
min_y = widgets.BoundedIntText(
value=min_value_y,
min=min_value_y,
max=max_value_y,
step=1,
description='y lower limit:',
)
max_y = widgets.BoundedIntText(
value=max_value_y,
min=min_value_y,
max=max_value_y,
step=1,
description='y upper limit:',
)
button = widgets.Button(description="Update image", button_style="info")
output = widgets.Output()
def on_button_clicked(b):
with output:
clear_output()
is_within_x_domain = (df.x > min_x.value) & (df.x < max_x.value)
is_within_y_domain = (df.y > min_y.value) & (df.y < max_y.value)
df2 = df[is_within_x_domain & is_within_y_domain]
plt.figure(figsize=(20, 4))
plt.scatter(df2["x"], df2["y"])
button.on_click(on_button_clicked) # Run when button is clicked
on_button_clicked(button) # Run when cell is run (so show image on start)
display(min_x)
display(max_x)
display(min_y)
display(max_y)
display(button, output)
You should be able to run the code in this colab notebook (as long as you are signed in into a google account): https://colab.research.google.com/drive/1eblVXf8J9V0VaObig1isJAbfadfuDIbK?usp=sharing
When I click on the update button, a new plot is generated, but the old plot is not deleted although I use clear_output()
in the function triggered by the button. Why is this and how can I clear the old plot before displaying the new one?
Thanks!
Upvotes: 0
Views: 1078
Reputation: 333
As far as I know, the Output widget can not handle matplotlib plots. In ipywidgets documents:
The Output widget can capture and display stdout, stderr and rich output generated by IPython.
So you can't use this widget. Here is a workaround (which is not neat):
import pandas as pd
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display, clear_output
df = pd.read_csv("https://raw.githubusercontent.com/juliangermek/aia/main/treasure_data.csv", sep=";")
min_value_x = df["x"].min()
max_value_x = df["x"].max()
min_value_y = df["y"].min()
max_value_y = df["y"].max()
min_x = widgets.BoundedIntText(
value=min_value_x,
min=min_value_x,
max=max_value_x,
step=1,
description='x lower limit:',
)
max_x = widgets.BoundedIntText(
value=max_value_x,
min=min_value_x,
max=max_value_x,
step=1,
description='x upper limit:',
)
min_y = widgets.BoundedIntText(
value=min_value_y,
min=min_value_y,
max=max_value_y,
step=1,
description='y lower limit:',
)
max_y = widgets.BoundedIntText(
value=max_value_y,
min=min_value_y,
max=max_value_y,
step=1,
description='y upper limit:',
)
button = widgets.Button(description="Update image", button_style="info")
def on_button_clicked(b):
clear_output()
display(min_x, max_x, min_y, max_y, button)
is_within_x_domain = (df.x > min_x.value) & (df.x < max_x.value)
is_within_y_domain = (df.y > min_y.value) & (df.y < max_y.value)
df2 = df[is_within_x_domain & is_within_y_domain]
plt.figure(figsize=(20, 4))
plt.scatter(df2["x"], df2["y"])
button.on_click(on_button_clicked) # Run when button is clicked
on_button_clicked(button) # Run when cell is run (so show image on start)
Upvotes: 2