CoolFace
Apppublic

lukasDduar/PythonTest

sourceHugging Facemitupdated 3y agoView on Hugging Face
0likes
app.py157 linesDownload Raw Back to root
1from pathlib import Path2from typing import List, Dict, Tuple3import matplotlib.colors as mpl_colors4 5import pandas as pd6import seaborn as sns7import shinyswatch8 9import shiny.experimental as x10from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui11 12sns.set_theme()13 14www_dir = Path(__file__).parent.resolve() / "www"15 16df = pd.read_csv(Path(__file__).parent / "penguins.csv", na_values="NA")17numeric_cols: List[str] = df.select_dtypes(include=["float64"]).columns.tolist()18species: List[str] = df["Species"].unique().tolist()19species.sort()20 21app_ui = x.ui.page_fillable(22    shinyswatch.theme.minty(),23    x.ui.layout_sidebar(24        x.ui.sidebar(25            # Artwork by @allison_horst26            ui.input_selectize(27                "xvar",28                "X variable",29                numeric_cols,30                selected="Bill Length (mm)",31            ),32            ui.input_selectize(33                "yvar",34                "Y variable",35                numeric_cols,36                selected="Bill Depth (mm)",37            ),38            ui.input_checkbox_group(39                "species", "Filter by species", species, selected=species40            ),41            ui.hr(),42            ui.input_switch("by_species", "Show species", value=True),43            ui.input_switch("show_margins", "Show marginal plots", value=True),44        ),45        ui.output_ui("value_boxes"),46        x.ui.output_plot("scatter", fill=True),47        ui.help_text(48            "Artwork by ",49            ui.a("@allison_horst", href="https://twitter.com/allison_horst"),50            class_="text-end",51        ),52        fill=True,53        fillable=True,54    ),55)56 57 58def server(input: Inputs, output: Outputs, session: Session):59    @reactive.Calc60    def filtered_df() -> pd.DataFrame:61        """Returns a Pandas data frame that includes only the desired rows"""62 63        # This calculation "req"uires that at least one species is selected64        req(len(input.species()) > 0)65 66        # Filter the rows so we only include the desired species67        return df[df["Species"].isin(input.species())]68 69    @output70    @render.plot71    def scatter():72        """Generates a plot for Shiny to display to the user"""73 74        # The plotting function to use depends on whether margins are desired75        plotfunc = sns.jointplot if input.show_margins() else sns.scatterplot76 77        plotfunc(78            data=filtered_df(),79            x=input.xvar(),80            y=input.yvar(),81            palette=palette,82            hue="Species" if input.by_species() else None,83            hue_order=species,84            legend=False,85        )86 87    @output88    @render.ui89    def value_boxes():90        df = filtered_df()91 92        def penguin_value_box(title: str, count: int, bgcol: str, showcase_img: str):93            return x.ui.value_box(94                title,95                count,96                {"class_": "pt-1 pb-0"},97                showcase=x.ui.bind_fill_role(98                    ui.tags.img(99                        {"style": "object-fit:contain;"},100                        src=showcase_img,101                    ),102                    item=True,103                ),104                theme_color=None,105                style=f"background-color: {bgcol};",106                height="90px",107                full_screen=True,108            )109 110        if not input.by_species():111            return penguin_value_box(112                "Penguins",113                len(df.index),114                bg_palette["default"],115                # Artwork by @allison_horst116                showcase_img="penguins.png",117            )118 119        value_boxes = [120            penguin_value_box(121                name,122                len(df[df["Species"] == name]),123                bg_palette[name],124                # Artwork by @allison_horst125                showcase_img=f"{name}.png",126            )127            for name in species128            # Only include boxes for _selected_ species129            if name in input.species()130        ]131 132        return x.ui.layout_column_wrap(1 / len(value_boxes), *value_boxes)133 134 135# "darkorange", "purple", "cyan4"136colors = [[255, 140, 0], [160, 32, 240], [0, 139, 139]]137colors = [(r / 255.0, g / 255.0, b / 255.0) for r, g, b in colors]138 139palette: Dict[str, Tuple[float, float, float]] = {140    "Adelie": colors[0],141    "Chinstrap": colors[1],142    "Gentoo": colors[2],143    "default": sns.color_palette()[0],  # type: ignore144}145 146bg_palette = {}147# Use `sns.set_style("whitegrid")` to help find approx alpha value148for name, col in palette.items():149    # Adjusted n_colors until `axe` accessibility did not complain about color contrast150    bg_palette[name] = mpl_colors.to_hex(sns.light_palette(col, n_colors=7)[1])  # type: ignore151 152 153app = App(154    app_ui,155    server,156    static_assets=str(www_dir),157)