CoolFace
Apppublic

anu111/python

sourceHugging Facemitupdated 3y agoView on Hugging Face
0likes
app.py156 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    ui.layout_sidebar(24        ui.panel_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            width=2,45        ),46        ui.panel_main(47            ui.output_ui("value_boxes"),48            x.ui.output_plot("scatter", fill=True),49            ui.help_text(50                "Artwork by ",51                ui.a("@allison_horst", href="https://twitter.com/allison_horst"),52                class_="text-end",53            ),54        ),55    ),56)57 58 59def server(input: Inputs, output: Outputs, session: Session):60    @reactive.Calc61    def filtered_df() -> pd.DataFrame:62        """Returns a Pandas data frame that includes only the desired rows"""63 64        # This calculation "req"uires that at least one species is selected65        req(len(input.species()) > 0)66 67        # Filter the rows so we only include the desired species68        return df[df["Species"].isin(input.species())]69 70    @output71    @render.plot72    def scatter():73        """Generates a plot for Shiny to display to the user"""74 75        # The plotting function to use depends on whether margins are desired76        plotfunc = sns.jointplot if input.show_margins() else sns.scatterplot77 78        plotfunc(79            data=filtered_df(),80            x=input.xvar(),81            y=input.yvar(),82            palette=palette,83            hue="Species" if input.by_species() else None,84            hue_order=species,85            legend=False,86        )87 88    @output89    @render.ui90    def value_boxes():91        df = filtered_df()92 93        def penguin_value_box(title: str, count: int, bgcol: str, showcase_img: str):94            return x.ui.value_box(95                title,96                count,97                {"class_": "pt-1 pb-0"},98                showcase=x.ui.as_fill_item(99                    ui.tags.img(100                        {"style": "object-fit:contain;"},101                        src=showcase_img,102                    )103                ),104                theme_color=None,105                style=f"background-color: {bgcol};",106            )107 108        if not input.by_species():109            return penguin_value_box(110                "Penguins",111                len(df.index),112                bg_palette["default"],113                # Artwork by @allison_horst114                showcase_img="penguins.png",115            )116 117        value_boxes = [118            penguin_value_box(119                name,120                len(df[df["Species"] == name]),121                bg_palette[name],122                # Artwork by @allison_horst123                showcase_img=f"{name}.png",124            )125            for name in species126            # Only include boxes for _selected_ species127            if name in input.species()128        ]129 130        return x.ui.layout_column_wrap(1 / len(value_boxes), *value_boxes)131 132 133# "darkorange", "purple", "cyan4"134colors = [[255, 140, 0], [160, 32, 240], [0, 139, 139]]135colors = [(r / 255.0, g / 255.0, b / 255.0) for r, g, b in colors]136 137palette: Dict[str, Tuple[float, float, float]] = {138    "Adelie": colors[0],139    "Chinstrap": colors[1],140    "Gentoo": colors[2],141    "default": sns.color_palette()[0],  # type: ignore142}143 144bg_palette = {}145# Use `sns.set_style("whitegrid")` to help find approx alpha value146for name, col in palette.items():147    # Adjusted n_colors until `axe` accessibility did not complain about color contrast148    bg_palette[name] = mpl_colors.to_hex(sns.light_palette(col, n_colors=7)[1])  # type: ignore149 150 151app = App(152    app_ui,153    server,154    static_assets=str(www_dir),155)156