{ "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 }