diff --git a/bar-demo.py b/bar-demo.py index a4b23a6..b1c5095 100644 --- a/bar-demo.py +++ b/bar-demo.py @@ -1,29 +1,71 @@ +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "altair==5.5.0", +# "marimo", +# "numpy==2.1.3", +# "pandas==2.2.3", +# "drawdata==0.3.6", +# ] +# /// + import marimo -__generated_with = "0.9.17" +__generated_with = "0.9.18" app = marimo.App(width="medium") +@app.cell(hide_code=True) +def __(mo, widget): + mo.md(f"""## BarWidget demo + + Let's say that you've got a house with solar panels. During some parts of the day you may use more or less energy and the sun might not be shining. You can draw this out on the barwidget shown below. + + {widget} + + As you update the bar widget the chart below will update. It shows you what the effect of a home battery might be if the day that you drew were to repeat itself. + """) + return + + @app.cell -def __(): - import marimo as mo - from drawdata import BarWidget - return BarWidget, mo +def __(out): + out + return @app.cell def __(BarWidget, mo): - widget = mo.ui.anywidget(BarWidget(height=400, width=700, n_bins=24)) - widget + widget = mo.ui.anywidget(BarWidget(height=200, width=700, n_bins=24, collection_names=["usage", "sunshine"])) return (widget,) +@app.cell(hide_code=True) +def __(pltr): + import altair as alt + + p1 = alt.Chart(pltr).mark_line(color="red", interpolate="step-after").encode(x="bin", y="cs") + p2 = alt.Chart(pltr).mark_area(interpolate="step-after").encode(x="bin", y="battery") + + total = pltr["battery"].sum() + + out = (p2 + p1).properties(width=700, title=f"Max battery cap: {pltr['battery'].max(): .2f} kWh, total: {total :.2f} kWh") + return alt, out, p1, p2, total + + +@app.cell +def __(): + import marimo as mo + from drawdata import BarWidget + return BarWidget, mo + + @app.cell(hide_code=True) def __(widget): import numpy as np df = widget.data_as_pandas - subset = df.loc[lambda d: d["collection"].isin(["collection3", "collection1"])] + subset = df.loc[lambda d: d["collection"].isin(["usage", "sunshine"])] return df, np, subset @@ -42,35 +84,20 @@ def add_stats(dfin): return ( dfin .pivot(columns="collection", index="bin", values="value") - .assign(balance=lambda d: d["collection3"] - d["collection1"]) + .assign(balance=lambda d: d["sunshine"] - d["usage"]) .assign(cs=lambda d: d["balance"].cumsum()) + .assign(cs=lambda d: np.where(d["cs"] > 5, 5, d["cs"])) .assign(battery=lambda d: np.where(d["cs"] > 0, d["cs"], 0)) .reset_index() ) - + pltr = subset.pipe(concat_days).sort_values(["collection", "bin"]).pipe(add_stats) return add_stats, concat_days, pd, pltr -@app.cell(hide_code=True) -def __(pltr): - import altair as alt - - p1 = alt.Chart(pltr).mark_line(color="red", interpolate="step-after").encode(x="bin", y="cs") - p2 = alt.Chart(pltr).mark_area(interpolate="step-after").encode(x="bin", y="battery") - - total = pltr["battery"].sum() - - (p2 + p1).properties(width=700, title=f"Max battery cap: {pltr['battery'].max(): .2f} kWh, total: {total :.2f} kWh") - return alt, p1, p2, total - - @app.cell def __(): - - - return diff --git a/drawdata/__init__.py b/drawdata/__init__.py index 700ae14..c1f7216 100644 --- a/drawdata/__init__.py +++ b/drawdata/__init__.py @@ -63,6 +63,21 @@ class BarWidget(anywidget.AnyWidget): """ A bar drawing widget that automatically can update a pandas/polars dataframe as your draw data. + + Parameters + ---------- + y_min : float + The minimum y value to display. + y_max : float + The maximum y value to display. + n_bins : int + The number of bins to display. + width : int + The width of the widget. + height : int + The height of the widget. + collection_names : list of str + The names of the collections to draw. """ _esm = Path(__file__).parent / 'static' / 'bar_widget.js' _css = Path(__file__).parent / 'static' / 'bar_widget.css' @@ -73,6 +88,10 @@ class BarWidget(anywidget.AnyWidget): width = traitlets.Int(800).tag(sync=True) height = traitlets.Int(550).tag(sync=True) collection_names = traitlets.List(["collection1", "collection2"]).tag(sync=True) + + def __init__(self, y_min=0.0, y_max=1.0, n_bins=24, width=800, height=550, collection_names=["collection1", "collection2"]): + super().__init__(y_min=y_min, y_max=y_max, n_bins=n_bins, width=width, height=height, collection_names=collection_names) + @property def data_as_pandas(self): import pandas as pd diff --git a/scatter-demo.py b/scatter-demo.py index 269bce4..c2aed65 100644 --- a/scatter-demo.py +++ b/scatter-demo.py @@ -1,7 +1,18 @@ +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "altair==5.5.0", +# "marimo", +# "numpy==2.1.3", +# "pandas==2.2.3", +# "drawdata==0.3.6", +# ] +# /// + import marimo -__generated_with = "0.9.17" -app = marimo.App(width="medium", layout_file="layouts/demo.grid.json") +__generated_with = "0.9.18" +app = marimo.App(width="medium") @app.cell @@ -30,6 +41,12 @@ def __(ScatterWidget, mo): return (widget,) +@app.cell +def __(widget): + widget.data_as_pandas + return + + @app.cell(hide_code=True) def __(widget): import altair as alt diff --git a/setup.py b/setup.py index a04033a..5fa45fc 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ def read(fname): setup( name="drawdata", - version="0.3.4", + version="0.3.6", description="draw a dataset from inside Jupyter", author="Vincent D. Warmerdam", packages=find_packages(exclude=["notebooks"]),