Spaces:
Sleeping
Sleeping
| #import datetime | |
| import json | |
| #import math | |
| # data analysis | |
| import numpy as np | |
| import pandas as pd | |
| # dashboard | |
| import panel as pn | |
| # plotting | |
| import altair as alt | |
| import holoviews as hv | |
| import hvplot.pandas # noqa | |
| import seaborn as sns | |
| import matplotlib | |
| import matplotlib.pyplot as plt | |
| import plotly.express as px | |
| from bokeh.models import ColumnDataSource | |
| from bokeh.plotting import figure as b_figure | |
| from matplotlib.figure import Figure | |
| from plotnine import ggplot, aes, geom_line, theme_matplotlib, theme_set | |
| # configure panel and plots | |
| pn.extension('ipywidgets', 'plotly', 'vega', 'vizzu', | |
| design='material', sizing_mode='fixed') | |
| hv.extension('bokeh', 'matplotlib', 'plotly') | |
| matplotlib.use('agg') | |
| # configure app | |
| DATA_DIR = 'data' | |
| JSON_FILE = 'tensorflow.timeline.purpose-to-type.json' | |
| # get data, cached | |
| def get_timeline_data(): | |
| with open(f'{DATA_DIR}/{JSON_FILE}', mode='r') as json_fp: | |
| return json.load(json_fp) | |
| # TODO: include the rest of the app | |
| # widgets | |
| repos_widget = pn.widgets.Select( | |
| name="repository", | |
| value="tensorflow", options=["tensorflow"], | |
| disabled=True | |
| ) | |
| # ----------------------------------------------------------- | |
| def create_figure_matplotlib(figsize=(4,3)): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| s = 1 + np.sin(2 * np.pi * t) | |
| # figure | |
| if figsize is None: | |
| fig = Figure() | |
| else: | |
| fig = Figure(figsize=figsize) | |
| ax = fig.subplots() | |
| # plot | |
| ax.plot(t, s) | |
| # decorations | |
| ax.set(xlabel='time (s)', ylabel='voltage (mV)', | |
| title='Voltage') | |
| ax.grid() | |
| # https://matplotlib.org/ipympl/examples/full-example.html | |
| # NOTE: might require ipympl to be installed | |
| # Hide the Figure name at the top of the figure | |
| fig.canvas.header_visible = False | |
| # Disable the resizing feature | |
| fig.canvas.resizable = False | |
| return fig | |
| def create_figure_seaborn(figsize=(4,3)): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| df = pd.DataFrame({ | |
| 'x': t, | |
| 'y': 1 + np.sin(2 * np.pi * t), | |
| }) | |
| # figure | |
| fig = Figure(figsize=figsize) | |
| ax = fig.subplots() | |
| # configure | |
| sns.set_theme() # 'default' theme | |
| # plot | |
| sns.lineplot(data=df, x='x', y='y', | |
| ax=ax) | |
| return fig | |
| def create_figure_pandas(figsize=(4,3)): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| df = pd.DataFrame({ | |
| 'x': t, | |
| 'y': 1 + np.sin(2 * np.pi * t), | |
| }) | |
| # figure | |
| fig = Figure(figsize=figsize) | |
| ax = fig.subplots() | |
| # plot | |
| df.plot(x='x', y='y', legend=False, | |
| xlabel='time (s)', ylabel='voltage (mV)', title='Voltage', | |
| ax=ax) | |
| return fig | |
| def create_figure_plotnine(): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| df = pd.DataFrame({ | |
| 'x': t, | |
| 'y': 1 + np.sin(2 * np.pi * t), | |
| }) | |
| # Set default theme for all the plots | |
| theme_set(theme_matplotlib()) | |
| # Basic Scatter Plot | |
| # - Gallery, points | |
| plot = ( | |
| ggplot(df, aes("x", "y")) | |
| + geom_line(color="blue") | |
| ) | |
| # draw the plot | |
| fig = plot.draw() | |
| plt.close(fig) # REMEMBER TO CLOSE THE FIGURE! | |
| return fig | |
| def create_figure_bokeh(): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| s = 1 + np.sin(2 * np.pi * t) | |
| # wrapped data | |
| source = ColumnDataSource(data=dict(x=t, y=s)) | |
| # configuring the plot | |
| # https://docs.bokeh.org/en/latest/docs/user_guide/interaction/tools.html#inspectors | |
| tooltips = [ | |
| ("index", "$index"), | |
| ("(x,y)", "($x, $y)"), | |
| ] | |
| # set up plot | |
| plot = b_figure(height=400, width=400, title="my sine wave", | |
| tools="crosshair,pan,reset,save,wheel_zoom,hover", | |
| tooltips=tooltips, | |
| x_range=[-0.1, 2.1], y_range=[-0.1, 2.1]) | |
| plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6) | |
| return plot | |
| def create_figure_hvplot_pandas(): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| df = pd.DataFrame({ | |
| 'x': t, | |
| 'y': 1 + np.sin(2 * np.pi * t), | |
| }) | |
| # plot | |
| plot = df.hvplot(x='x', y='y', | |
| value_label='sin(2πt)+1', | |
| #responsive = True, # incompatible with fixed size | |
| height = 500, width = 620, # incompatible with responsive mode | |
| title='f(t) = sin(2πt)+1', | |
| legend='top') | |
| return plot | |
| def create_figure_hv(): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| data = { | |
| "x": t, | |
| "y": 1 + np.sin(2 * np.pi * t), | |
| } | |
| # plot | |
| hv_box = hv.Scatter(data, kdims="x", vdims="y").opts() | |
| return hv_box | |
| def create_figure_plotly(): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| data = { | |
| "x": t, | |
| "y": 1 + np.sin(2 * np.pi * t), | |
| } | |
| # create plot | |
| fig = px.line( | |
| data, x="x", y="y", | |
| # ??? 'fixed' sizing mode requires width and height to be set: PlotlyPlot(id='p1275', ...) | |
| width=500, height=420, # required for 'fixed' sizing mode | |
| ) | |
| # configure plot | |
| fig.update_traces(mode="lines", line=dict(width=1)) | |
| return fig | |
| def create_figure_altair(): | |
| # data | |
| t = np.arange(0.0, 2.0, 0.01) | |
| df = pd.DataFrame({ | |
| "x": t, | |
| "y": 1 + np.sin(2 * np.pi * t), | |
| }) | |
| # create plot | |
| # https://altair-viz.github.io/user_guide/marks/line.html | |
| chart = alt.Chart(df).mark_line( | |
| point=alt.OverlayMarkDef(opacity=0, size=1), | |
| ).encode( | |
| x='x', | |
| y='y', | |
| tooltip=['x', 'y'], # not used? | |
| ).properties( | |
| # ??? 'fixed' sizing mode requires width and height to be set: VegaPlot(id='p1282', ...) | |
| width =500, | |
| height=420, | |
| ).interactive() | |
| return chart | |
| # https://panel.holoviz.org/reference/panes/HoloViews.html#dynamic | |
| def hvplot_widgeted(height = 300): | |
| plot = create_figure_hvplot_pandas() | |
| plot_pane = pn.pane.HoloViews(plot, | |
| backend='bokeh', | |
| sizing_mode="fixed", height=height) | |
| backend_widget = pn.widgets.RadioButtonGroup.from_param( | |
| plot_pane.param.backend, | |
| button_type="primary", button_style="outline", | |
| ) | |
| return pn.Column(backend_widget, plot_pane) | |
| def wizzu_pane(): | |
| # data (may use DataFrame instead) | |
| t = np.arange(0.0, 2.0, 0.01) | |
| data = { | |
| "x": t, | |
| "y": 1 + np.sin(2 * np.pi * t), | |
| } | |
| df = pd.DataFrame(data) | |
| # plot configuration | |
| config = { | |
| 'geometry': 'line', | |
| 'x': 'x', 'y': 'y', | |
| 'title': 'sin(2πt)+1', | |
| } | |
| animate = { | |
| 'config': { | |
| 'channels': { | |
| 'x': { | |
| 'range': { | |
| 'min': 'auto', | |
| 'max': 'auto' | |
| } | |
| }, | |
| 'y': { | |
| 'range': { | |
| 'min': 'auto', | |
| 'max': 'auto', | |
| } | |
| } | |
| } | |
| } | |
| } | |
| # pane | |
| vizzu = pn.pane.Vizzu( | |
| df, config=config, animation=animate, | |
| duration=400, tooltip=True, | |
| sizing_mode='fixed', width=500, height=425, | |
| ) | |
| return vizzu | |
| # the application | |
| pn.template.MaterialTemplate( | |
| site="Panel", | |
| title="Demo of various plotting solutions", | |
| sidebar_width=300, | |
| sidebar=[ | |
| repos_widget, # disabled, and UNBOUND! | |
| ], | |
| main=[ | |
| pn.pane.Str("Plots would be shown here"), | |
| pn.FlexBox( | |
| pn.Card( | |
| pn.pane.Matplotlib(create_figure_matplotlib(), | |
| format="svg", tight=True, | |
| width=500, height=425), | |
| header="Matplotlib (svg)", | |
| ), | |
| pn.Card( | |
| pn.pane.Matplotlib(create_figure_matplotlib(figsize=None), | |
| interactive=True, tight=True, | |
| width=500, height=425), | |
| header="interactive Matplotlib (via ipympl) - BUGGY!!!", | |
| ), | |
| pn.Card( | |
| pn.pane.Matplotlib(create_figure_seaborn(), | |
| format="png", tight=True, | |
| width=500, height=425), | |
| header="seaborn (png)", | |
| ), | |
| pn.Card( | |
| pn.pane.Matplotlib(create_figure_pandas(), | |
| format="png", tight=True, | |
| width=500, height=425), | |
| header="pandas (png)", | |
| ), | |
| # TODO: https://panel.holoviz.org/reference/panes/Perspective.html | |
| pn.Card( | |
| pn.pane.Matplotlib(create_figure_plotnine(), | |
| format="svg", tight=True, | |
| width=500, height=425), | |
| header="plotnine / ggplot2 (png)", | |
| ), | |
| pn.Card( | |
| pn.Row( | |
| pn.pane.Bokeh(create_figure_bokeh(), theme="dark_minimal", height=600), | |
| pn.pane.Markdown(r""" | |
| - Pan/Drag Tools | |
| - 'box_select' | |
| - 'box_zoom' | |
| - 'lasso_select' | |
| - **'pan'**, 'xpan', 'ypan' | |
| - Click/Tap Tools | |
| - 'poly_select' | |
| - 'tap' | |
| - Scroll/Pinch Tools | |
| - **'wheel_zoom'**, 'xwheel_zoom', 'ywheel_zoom' | |
| - 'xwheel_pan', 'ywheel_pan' | |
| - Actions | |
| - 'examine' | |
| - 'undo' | |
| - 'redo' | |
| - **'reset'** | |
| - **'save'** | |
| - 'zoom_in', 'xzoom_in', 'yzoom_in' | |
| - 'zoom_out', 'xzoom_out', 'yzoom_out' | |
| - Inspectors | |
| - **'crosshair'** | |
| - **'hover'** (figure configurable with `tooltips=`) | |
| - Edit Tools | |
| - ... | |
| """), | |
| ), | |
| header="Bokeh (theme='dark_minimal')", | |
| ), | |
| # TODO?: https://panel.holoviz.org/reference/panes/ECharts.html | |
| pn.Card( | |
| create_figure_hvplot_pandas(), | |
| header="hvPlot (pandas.hvplot)", | |
| ), | |
| pn.Card( | |
| hvplot_widgeted(height=600), | |
| header="hvPlot - select backend", | |
| ), | |
| pn.Card( | |
| pn.pane.HoloViews(create_figure_hv(), | |
| sizing_mode='fixed', height=600), | |
| header="HoloViews (hv.Scatter)", | |
| ), | |
| pn.Card( | |
| pn.pane.Plotly(create_figure_plotly(), | |
| sizing_mode='fixed', width=500, height=425), | |
| header="Plotly.Express", | |
| ), | |
| pn.Card( | |
| pn.pane.Vega(create_figure_altair(), | |
| sizing_mode='fixed', width=500, height=425), | |
| # ALTERNATIVE: pn.panel(create_figure_altair()) | |
| header="Vega (using Altair)", | |
| ), | |
| pn.Card( | |
| wizzu_pane(), | |
| header="Vizzu JavaScript library - not configured!!!", | |
| ), | |
| ), | |
| ], | |
| ).servable() | |