From 475f0e2ba4e28582c3f3f559fb4d2dd8a5b2a995 Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Fri, 9 Feb 2024 13:11:31 +0000 Subject: [PATCH] clean up --- doc/tutorials/basic/build_image_classifier.md | 53 ++++++++++--------- doc/tutorials/basic/build_report.md | 29 ++++++---- doc/tutorials/basic/build_todo.md | 10 ---- doc/tutorials/index.md | 27 ---------- 4 files changed, 46 insertions(+), 73 deletions(-) diff --git a/doc/tutorials/basic/build_image_classifier.md b/doc/tutorials/basic/build_image_classifier.md index 60959b5110..b74c9eeff7 100644 --- a/doc/tutorials/basic/build_image_classifier.md +++ b/doc/tutorials/basic/build_image_classifier.md @@ -15,23 +15,19 @@ When we ask you to *run the code* in the sections below, you may either execute ## Create the App -TODO - -- Remove Design Reference -- More clearly define `image` and `label` state. -- Make the interface more compatible with Gradio by minimizing the surface area between inputs and outputs. -- Consider using another plotting library than hvplot. `hbar` has many issues and does not support transitions. Use Vizzu, ECharts, or Plotly? +Run the code below. ```{pyodide} -# Design Reference: https://github.com/pytholic/gradio-image-classificaiton/blob/main/resources/demo.png?raw=true -import panel as pn -from PIL import Image import random -import pandas as pd +from io import BytesIO from time import sleep + import hvplot.pandas +import pandas as pd import requests -from io import BytesIO +from PIL import Image + +import panel as pn IMAGE_DIM = 350 @@ -39,21 +35,26 @@ pn.extension(design="material", sizing_mode="stretch_width") ## Transformations + @pn.cache def get_pil_image(url): response = requests.get(url) return Image.open(BytesIO(response.content)) + @pn.cache def get_plot(label): data = pd.Series(label).sort_values() - return data.hvplot.barh(title="Prediction", ylim=(0,100)).opts(default_tools=[]) + return data.hvplot.barh(title="Prediction", ylim=(0, 100)).opts(default_tools=[]) + ## Custom Components + def get_label_view(fn, image: Image): return get_plot(fn(image)) + def get_image_button(url, image_pane): button = pn.widgets.Button( width=100, @@ -65,8 +66,10 @@ def get_image_button(url, image_pane): pn.bind(handle_example_click, button, url, image_pane, watch=True) return button + ## Event Handlers + def handle_example_click(event, url, image_pane): image_pane.object = get_pil_image(url) @@ -75,6 +78,7 @@ def handle_file_upload(value, image_pane): file = BytesIO(value) image_pane.object = Image.open(file) + def image_classification_interface(fn, examples): ## State @@ -107,7 +111,13 @@ def image_classification_interface(fn, examples): ## Views label_view = pn.Row( - pn.panel(pn.bind(get_label_view, fn=fn, image=image_view.param.object), defer_load=True, loading_indicator=True, height=IMAGE_DIM, width=IMAGE_DIM) + pn.panel( + pn.bind(get_label_view, fn=fn, image=image_view.param.object), + defer_load=True, + loading_indicator=True, + height=IMAGE_DIM, + width=IMAGE_DIM, + ) ) ## Layouts @@ -129,6 +139,7 @@ def image_classification_interface(fn, examples): ) return pn.FlexBox(input_component, output_component) + def predict(image: Image): # Replace with your own image classification model sleep(1.5) @@ -144,9 +155,9 @@ def predict(image: Image): EXAMPLES = [ # Replace with your own examples - "https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Windmills_D1-D4_%28Thornton_Bank%29.jpg/220px-Windmills_D1-D4_%28Thornton_Bank%29.jpg", - "https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Solar_cell.png/220px-Solar_cell.png", - "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a3/Overhead_View_of_Tehachapi_Energy_Storage_Project%2C_Tehachapi%2C_CA.png/220px-Overhead_View_of_Tehachapi_Energy_Storage_Project%2C_Tehachapi%2C_CA.png", + "https://assets.holoviz.org/panel/tutorials/wind_turbine.png", + "https://assets.holoviz.org/panel/tutorials/solar_panel.png", + "https://assets.holoviz.org/panel/tutorials/battery_storage.png", ] image_classification_interface(fn=predict, examples=EXAMPLES).servable() @@ -157,12 +168,6 @@ Try to - Click an example image - Upload an `.png` or `.jpg` image file -## Break it down - -We will now break down the example together to get a better understanding of the code. - -COMING UP - ## Recap In this tutorial we have built an *Image Classifier* that can detect wind turbines. We will support @@ -171,7 +176,3 @@ In this tutorial we have built an *Image Classifier* that can detect wind turbin - Using an example image file - Viewing the image file - Viewing the predicted result - -## Resources - -COMING UP diff --git a/doc/tutorials/basic/build_report.md b/doc/tutorials/basic/build_report.md index e3b02bc6c7..06a514d5cc 100644 --- a/doc/tutorials/basic/build_report.md +++ b/doc/tutorials/basic/build_report.md @@ -22,10 +22,25 @@ pn.extension("vega", sizing_mode="stretch_width") # Extract Data -TEXT ="""Lorem ipsum dolor sit amet, consectetur adipiscing elit. \ -Proin scelerisque in arcu tristique sollicitudin. Aliquam ornare bibendum blandit."""* 10 +TEXT ="""# Wind Turbine -df = pd.read_csv("https://assets.holoviz.org/panel/tutorials/turbines.csv.gz") +A wind turbine is a device that converts the kinetic energy of wind into \ +[electrical energy](https://en.wikipedia.org/wiki/Electrical_energy). + +The most visible part of a wind turbine is its *rotor*, which typically consists of two or three long *blades* attached to a central hub. These blades are meticulously designed to efficiently capture the energy of the wind as it passes through them. Through careful aerodynamic engineering, the shape, length, and angle of the blades are optimized to maximize the amount of kinetic energy they can extract from the wind. + +As the wind blows, it causes the rotor blades to rotate. This rotational motion is transferred to a generator housed within the turbine's nacelle, a large enclosure situated atop a tall tower. The generator converts the mechanical energy of the rotating blades into electrical energy through the principles of electromagnetic induction. This electricity is then transmitted via cables down the tower and into the electrical grid for distribution to homes, businesses, and industries. + +The height of the tower plays a crucial role in the efficiency of a wind turbine. By elevating the rotor assembly high above the ground, turbines can access stronger and more consistent wind speeds, which translates to higher energy production. Taller towers also help minimize the impact of surface friction and turbulence near the ground, allowing the rotor blades to operate more smoothly and efficiently. + +Read more [here](https://en.wikipedia.org/wiki/Wind_turbine). +""" + +@pn.cache +def get_data(): + return pd.read_csv("https://assets.holoviz.org/panel/tutorials/turbines.csv.gz") + +df = get_data() # Transform Data @@ -147,7 +162,7 @@ report.servable() ``` :::{note} -If the code was run in a notebook or Python file, the report will have been saved to the file `report.html`. +If the code was run in a notebook or Python file, the report will have been saved by `report.save("report.html")` to the file `report.html`. ::: Please verify that the file `report.html` has been created. @@ -158,12 +173,6 @@ Attach the `report.html` file generated in the previous section to an email and 🥳 Congrats! Together, we have successfully created and distributed an interactive report based on DataFrames and one of our favorite plotting libraries. This is an amazing achievement! -## Break it down - -We will now break down the example together to get a better understanding of the code. - -COMING UP. - ## Recap In this section we have built a *Wind Turbine Report* with a nice user experience, exported it to `.html` and distributed it via email. diff --git a/doc/tutorials/basic/build_todo.md b/doc/tutorials/basic/build_todo.md index 3bf61c6e5c..aba6dead09 100644 --- a/doc/tutorials/basic/build_todo.md +++ b/doc/tutorials/basic/build_todo.md @@ -122,16 +122,6 @@ Let's perform the following actions: A todo app can be built in many other ways. The main purpose of this example is for all of us to acquire the basic skills needed to develop *stateful*, *dynamically updating* apps like this one. ::: -## Break it down - -We will now break down the example together to get a better understanding of the code. - -COMING UP - ## Recap In this section, we have built a *Todo App* with many features. We needed to combine many of the things we have learned so far. - -## Resources - -COMING UP diff --git a/doc/tutorials/index.md b/doc/tutorials/index.md index 98263804bc..d42bf5d53f 100644 --- a/doc/tutorials/index.md +++ b/doc/tutorials/index.md @@ -69,31 +69,4 @@ After completing these tutorials you can call your self a Panel *Rock Star*. basic/index intermediate/index expert/index -param -interactivity -layouts -styling ``` - -## Move - -Find a new home for the below - -::::{grid} 1 2 2 3 -:gutter: 1 1 1 2 - -:::{grid-item-card} {octicon}`plug;2.5em;sd-mr-1` Param -:link: param -:link-type: doc - -Panel and other projects in the HoloViz ecosystem all built on Param. In this section you will learn the basic concepts behind Param that you need to know to become an effective user of Panel. -::: - -:::{grid-item-card} {octicon}`pulse;2.5em;sd-mr-1` Interactivity -:link: interactivity -:link-type: doc - -In this section you learn how to leverage Parameters and dependencies on parameters to add interactivity. In particular we will focus on implementing interactivity through reactivity, rather than the more imperative style of programming you might be used to from other UI frameworks. -::: - -::::