I am creating interactive plots using io and ipywidgets. The idea is to be able to select which 'riskdriver' (rd) plot to display. I have the following code which works for each individual plot.
import matplotlib.pyplot as plt
import numpy as np
import io
import base64
from PIL import Image
from ipywidgets import interact
@interact(rd = ['all', 'rd1', 'rd2', 'rd3', 'rd4'])
def display_plot(rd):
my_results = {}
for rd in ['rd1', 'rd2', 'rd3', 'rd4']:
f = io.BytesIO()
a = np.random.rand(10)
p = plt.bar(range(len(a)), a)
plt.savefig(f, format = "png")
my_results[rd] = f
plt.close()
img = Image.open(io.BytesIO(my_results[rd].getvalue()))
display(img)
As you will notice, the code creates an option 'all', however, I am not sure how to adjust the code to actually display all plots when selecting this option. Can someone please help me with this?
You can use interact (or interactive) to made like this:
import matplotlib.pyplot as plt
from ipywidgets import interactive, Output
rds = ['rd1', 'rd2', 'rd3', 'rd4']
all_outs = []
my_results = {}
for rd in rds:
current_out = Output()
a = np.random.rand(10)
p = plt.bar(range(len(a)), a)
with current_out:
plt.show()
my_results[rd] = current_out
all_outs.append(current_out)
plt.close()
def change_image(value):
if value != "all":
display(my_results[value])
else:
display(HBox([my_results[img] for img in rds]))
interactive(change_image, value=["all"]+rds)
But, ipywidgets
is more powerful than this, so you can use a widget named Tab
with Output
, because Tabs only accepts another widgets:
import matplotlib.pyplot as plt
from ipywidgets import Output, Tab, HBox
import numpy as np
rds = ['rd1', 'rd2', 'rd3', 'rd4']
childrens = []
for rd in rds:
current_out = Output()
a = np.random.rand(10)
p = plt.bar(range(len(a)), a)
with current_out:
plt.show()
childrens.append(current_out)
plt.close()
childrens.insert(0, HBox(*[childrens]))
tab = Tab(childrens)
tab.titles = ["all"] + rds
display(tab)