{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "43045e3c7c5e433eb871102517731c79",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(FileUpload(value={}, description='Upload', multiple=True), HTML(value=\"Use the above 'Upload' b…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import numpy as np\n",
"from traitlets import dlink\n",
"import ipywidgets as widgets\n",
"from IPython.display import display\n",
"from io import StringIO\n",
"import glob\n",
"import random \n",
"\n",
"# widgets\n",
"file_uploader = widgets.FileUpload(multiple=True )\n",
"#file_name = widgets.Text()\n",
"#files = glob.glob(\"*.xlsx\")\n",
"#files = glob.glob(\"*.csv\")\n",
"files = glob.glob(\"*.tsv\")\n",
"#print(files) # FOR DEBUGGING ONLY\n",
"current_file = None\n",
"\n",
"#upload_suggest = widgets.Label(value=\"Use above button to upload your data file if not listed among the choices below.)\")\n",
"#select_markdown = widgets.HTML(value=markdown.markdown(\"\"\"Use above button to upload your data file if not among the choices you see listed below.
**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\n",
"select_markdown = widgets.HTML(value=\"Use the above 'Upload' button to \"\n",
" \"upload your data file if it is not among the choices you see \"\n",
" \"listed below.
Click on the file name among list below \"\n",
" \"to select the data to plot and then click the \"\n",
" \"'Plot Selected' button.\")\n",
"\n",
"select_file = widgets.Select(options = files, description='Data files:')\n",
"button = widgets.Button(description=\"Plot Selected\")\n",
"ax = None\n",
"out = widgets.Output()\n",
"\n",
"@out.capture(clear_output=True,wait=True)\n",
"def on_button_clicked(b):\n",
" global file_uploader,select_file, current_file, ax\n",
" # get data file to be used\n",
" current_file = select_file.value\n",
" print(f\"Using data from:\\t{current_file}\")\n",
" # bring data into Pandas\n",
" import pandas as pd\n",
" import matplotlib.pyplot as plt\n",
" import numpy as np\n",
" import seaborn as sns\n",
" from mpl_toolkits.mplot3d import Axes3D\n",
" from ipywidgets import interact\n",
" from ipywidgets.widgets import FloatSlider, IntSlider, Dropdown\n",
" #wines = pd.read_excel(current_file) # Uncomment for Excel files\n",
" #wines = pd.read_csv(current_file) # Uncomment for CSV files\n",
" wines = pd.read_csv(current_file, sep='\\t')\n",
" #print(wines.head(random.randint(2, 12) ))\n",
" #construct or update plot\n",
" \n",
" if ax is None:\n",
" '''\n",
" fig1, axes1 = plt.subplots()\n",
" df.hist(ax = axes1)\n",
" '''\n",
" # BOTH `plt.show(fig1)` and `plt.show(block=True)` seem to work\n",
" #plt.show(fig1) # based on https://stackoverflow.com/a/51060721/8508004\n",
" #plt.show(block=True) # based on https://stackoverflow.com/a/61993497/8508004\n",
" xs = wines['residual sugar']\n",
" ys = wines['fixed acidity']\n",
" zs = wines['alcohol']\n",
" cmaps = ['coolwarm', 'viridis', 'magma','plasma','RdYlBu','YlGnBu','hsv']\n",
" v_angles = [\"30, 185\",\"50, 185\",\"230,110\",\"1,140\"]\n",
"\n",
" view_widget = Dropdown(options=v_angles)\n",
" elevation_widget= IntSlider(value=30, min=0, max=360,step=5, continuous_update=False)\n",
" azimuth_widget= IntSlider(value=185, min=0, max=360,step=5, continuous_update=False)\n",
" def update_elevation_and_azimuth(*args):\n",
" view_nums = view_widget.value.split(\",\")\n",
" view_nums = [int(x) for x in view_nums]\n",
" elevation_widget.value, azimuth_widget.value = view_nums\n",
" view_widget.observe(update_elevation_and_azimuth, 'value')\n",
"\n",
" def plot_data(opacity, cmap, coloring,marker_size,view_choice,elevation,azimuth):\n",
" fig = plt.figure(figsize=(9.5, 6))\n",
" ax = fig.add_subplot(111, projection='3d')\n",
" #norm = mpl.colors.Normalize(vmin=min(wines[coloring],), vmax=max(wines[coloring],))\n",
" g = ax.scatter(xs, ys, zs, s=marker_size, alpha=opacity, edgecolors='w', marker='o', depthshade=False, c=wines[coloring], cmap=cmap)\n",
" ax.view_init(elevation,azimuth)\n",
" ax.set_xlabel('Residual Sugar')\n",
" ax.set_ylabel('Fixed Acidity')\n",
" ax.set_zlabel('Alcohol')\n",
" clb = fig.colorbar(g)\n",
" clb.solids.set_edgecolor(\"face\") #based on https://stackoverflow.com/a/5495912/8508004; \n",
" # addition of `.solids.set_edgecolor(\"face\")` based on https://matplotlib.org/3.1.0/api/_as_gen/matplotlib.pyplot.colorbar.html to \n",
" # avoid banding seen with just `fig.colorbar(g)` along with ipywidgets use; note it needed further adjusting to \n",
" # clb.solids.set_edgecolor(\"face\") when added title to colorbar based on https://stackoverflow.com/a/33740567/8508004\n",
" clb.ax.set_title(coloring) #adding title based on https://stackoverflow.com/a/33740567/8508004\n",
" plt.show()\n",
"\n",
" p = interact(plot_data,\n",
" opacity=FloatSlider(value=0.75, min=0, max=1.0, step=0.05, readout_format='.3f', continuous_update=False),\n",
" cmap=Dropdown(value='magma',options=cmaps),\n",
" coloring=Dropdown(value='alcohol',options=['residual sugar','fixed acidity','alcohol']),\n",
" marker_size= IntSlider(value=50, min=10, max=180,step=10, continuous_update=False),\n",
" view_choice=view_widget,\n",
" elevation= elevation_widget,\n",
" azimuth= azimuth_widget\n",
" )\n",
" else:\n",
" print(\"updating...\")\n",
" #ax = fig.add_subplot(111, projection='3d')\n",
" #display(fig1)\n",
" vbox.children = [file_uploader, select_markdown, select_file,button, out]\n",
" \n",
"\n",
"button.on_click(on_button_clicked)\n",
"vbox = widgets.VBox([file_uploader, select_markdown, select_file,button])\n",
"\n",
"def on_file_upload(change):\n",
" global file_uploader,select_file, current_file\n",
" print(change['new'])\n",
" #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\n",
" for details_dict in change['new']:\n",
"\n",
" #files.append(filename) #worked with `for filename in change['new'].keys():`\n",
" files.append(details_dict['name'])\n",
"\n",
" #with open(details_dict['name'], \"wb\") as f: #worked with `for filename in change['new'].keys():`\n",
" with open(details_dict['name'], \"wb\") as f:\n",
" #f.write(change['new'][filename]['content']) #worked with `for filename in change['new'].keys():`\n",
" f.write(details_dict['content'])\n",
" #select_file.options=tuple(files)\n",
"\n",
" current_file = select_file.value\n",
" select_file.options=tuple(files)\n",
" select_file.value\n",
" #print(current_file)\n",
"\n",
"# links between widgets\n",
"#color_picker.observe(change_input, 'value')\n",
"#dlink((file_uploader, 'value'), (select_file, 'value'), get_name)\n",
"#file_picker.observe(change_input, 'value')\n",
"file_uploader.observe(on_file_upload, 'value')\n",
"\n",
"vbox"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
},
"rise": {
"autolaunch": true,
"enable_chalkboard": true,
"scroll": true,
"theme": "white",
"transition": "zoom"
}
},
"nbformat": 4,
"nbformat_minor": 4
}