import numpy as np
from traitlets import dlink
import ipywidgets as widgets
from IPython.display import display
from io import StringIO
import glob
import random
# widgets
file_uploader = widgets.FileUpload(multiple=True )
#file_name = widgets.Text()
#files = glob.glob("*.xlsx")
#files = glob.glob("*.csv")
files = glob.glob("*.tsv")
#print(files) # FOR DEBUGGING ONLY
current_file = None
#upload_suggest = widgets.Label(value="Use above button to upload your data file if not listed among the choices below.)")
#select_markdown = widgets.HTML(value=markdown.markdown("""Use above button to upload your data file if not among the choices you see listed below.<br/>**Choose the file with the data to plot from below**:""")) # based on https://github.com/jupyter-widgets/ipywidgets/issues/2428#issuecomment-500084610 and https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20List.html#HTML ; need to pip install markdown first and import it
select_markdown = widgets.HTML(value="Use the above 'Upload' button to "
"upload your data file if it is not among the choices you see "
"listed below.<br/><b>Click on the file name among list below "
"to select the data to plot</b> and then click the "
"'Plot Selected' button.")
select_file = widgets.Select(options = files, description='Data files:')
button = widgets.Button(description="Plot Selected")
ax = None
out = widgets.Output()
@out.capture(clear_output=True,wait=True)
def on_button_clicked(b):
global file_uploader,select_file, current_file, ax
# get data file to be used
current_file = select_file.value
print(f"Using data from:\t{current_file}")
# bring data into Pandas
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from mpl_toolkits.mplot3d import Axes3D
from ipywidgets import interact
from ipywidgets.widgets import FloatSlider, IntSlider, Dropdown
#wines = pd.read_excel(current_file) # Uncomment for Excel files
#wines = pd.read_csv(current_file) # Uncomment for CSV files
wines = pd.read_csv(current_file, sep='\t')
#print(wines.head(random.randint(2, 12) ))
#construct or update plot
if ax is None:
'''
fig1, axes1 = plt.subplots()
df.hist(ax = axes1)
'''
# BOTH `plt.show(fig1)` and `plt.show(block=True)` seem to work
#plt.show(fig1) # based on https://stackoverflow.com/a/51060721/8508004
#plt.show(block=True) # based on https://stackoverflow.com/a/61993497/8508004
xs = wines['residual sugar']
ys = wines['fixed acidity']
zs = wines['alcohol']
cmaps = ['coolwarm', 'viridis', 'magma','plasma','RdYlBu','YlGnBu','hsv']
v_angles = ["30, 185","50, 185","230,110","1,140"]
view_widget = Dropdown(options=v_angles)
elevation_widget= IntSlider(value=30, min=0, max=360,step=5, continuous_update=False)
azimuth_widget= IntSlider(value=185, min=0, max=360,step=5, continuous_update=False)
def update_elevation_and_azimuth(*args):
view_nums = view_widget.value.split(",")
view_nums = [int(x) for x in view_nums]
elevation_widget.value, azimuth_widget.value = view_nums
view_widget.observe(update_elevation_and_azimuth, 'value')
def plot_data(opacity, cmap, coloring,marker_size,view_choice,elevation,azimuth):
fig = plt.figure(figsize=(9.5, 6))
ax = fig.add_subplot(111, projection='3d')
#norm = mpl.colors.Normalize(vmin=min(wines[coloring],), vmax=max(wines[coloring],))
g = ax.scatter(xs, ys, zs, s=marker_size, alpha=opacity, edgecolors='w', marker='o', depthshade=False, c=wines[coloring], cmap=cmap)
ax.view_init(elevation,azimuth)
ax.set_xlabel('Residual Sugar')
ax.set_ylabel('Fixed Acidity')
ax.set_zlabel('Alcohol')
clb = fig.colorbar(g)
clb.solids.set_edgecolor("face") #based on https://stackoverflow.com/a/5495912/8508004;
# addition of `.solids.set_edgecolor("face")` based on https://matplotlib.org/3.1.0/api/_as_gen/matplotlib.pyplot.colorbar.html to
# avoid banding seen with just `fig.colorbar(g)` along with ipywidgets use; note it needed further adjusting to
# clb.solids.set_edgecolor("face") when added title to colorbar based on https://stackoverflow.com/a/33740567/8508004
clb.ax.set_title(coloring) #adding title based on https://stackoverflow.com/a/33740567/8508004
plt.show()
p = interact(plot_data,
opacity=FloatSlider(value=0.75, min=0, max=1.0, step=0.05, readout_format='.3f', continuous_update=False),
cmap=Dropdown(value='magma',options=cmaps),
coloring=Dropdown(value='alcohol',options=['residual sugar','fixed acidity','alcohol']),
marker_size= IntSlider(value=50, min=10, max=180,step=10, continuous_update=False),
view_choice=view_widget,
elevation= elevation_widget,
azimuth= azimuth_widget
)
else:
print("updating...")
#ax = fig.add_subplot(111, projection='3d')
#display(fig1)
vbox.children = [file_uploader, select_markdown, select_file,button, out]
button.on_click(on_button_clicked)
vbox = widgets.VBox([file_uploader, select_markdown, select_file,button])
def on_file_upload(change):
global file_uploader,select_file, current_file
print(change['new'])
#for filename in change['new'].keys(): #worked last time I tried, now `change['new']` is a tuple for each file with a dictionary as each item
for details_dict in change['new']:
#files.append(filename) #worked with `for filename in change['new'].keys():`
files.append(details_dict['name'])
#with open(details_dict['name'], "wb") as f: #worked with `for filename in change['new'].keys():`
with open(details_dict['name'], "wb") as f:
#f.write(change['new'][filename]['content']) #worked with `for filename in change['new'].keys():`
f.write(details_dict['content'])
#select_file.options=tuple(files)
current_file = select_file.value
select_file.options=tuple(files)
select_file.value
#print(current_file)
# links between widgets
#color_picker.observe(change_input, 'value')
#dlink((file_uploader, 'value'), (select_file, 'value'), get_name)
#file_picker.observe(change_input, 'value')
file_uploader.observe(on_file_upload, 'value')
vbox