RobioAI/DeepLearning
0
1from pathlib import Path2from typing import List, Dict, Tuple3import matplotlib.colors as mpl_colors4 5import pandas as pd6import seaborn as sns7import shinyswatch8 9from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui10 11sns.set_theme()12 13www_dir = Path(__file__).parent.resolve() / "www"14 15df = pd.read_csv(Path(__file__).parent / "penguins.csv", na_values="NA")16numeric_cols: List[str] = df.select_dtypes(include=["float64"]).columns.tolist()17species: List[str] = df["Species"].unique().tolist()18species.sort()19 20app_ui = ui.page_fillable(21 shinyswatch.theme.minty(),22 ui.layout_sidebar(23 ui.sidebar(24 # Artwork by @allison_horst25 ui.input_selectize(26 "xvar",27 "X variable",28 numeric_cols,29 selected="Bill Length (mm)",30 ),31 ui.input_selectize(32 "yvar",33 "Y variable",34 numeric_cols,35 selected="Bill Depth (mm)",36 ),37 ui.input_checkbox_group(38 "species", "Filter by species", species, selected=species39 ),40 ui.hr(),41 ui.input_switch("by_species", "Show species", value=True),42 ui.input_switch("show_margins", "Show marginal plots", value=True),43 ),44 ui.output_ui("value_boxes"),45 ui.output_plot("scatter", fill=True),46 ui.help_text(47 "Artwork by ",48 ui.a("@allison_horst", href="https://twitter.com/allison_horst"),49 class_="text-end",50 ),51 ),52)53 54 55def server(input: Inputs, output: Outputs, session: Session):56 @reactive.Calc57 def filtered_df() -> pd.DataFrame:58 """Returns a Pandas data frame that includes only the desired rows"""59 60 # This calculation "req"uires that at least one species is selected61 req(len(input.species()) > 0)62 63 # Filter the rows so we only include the desired species64 return df[df["Species"].isin(input.species())]65 66 @output67 @render.plot68 def scatter():69 """Generates a plot for Shiny to display to the user"""70 71 # The plotting function to use depends on whether margins are desired72 plotfunc = sns.jointplot if input.show_margins() else sns.scatterplot73 74 plotfunc(75 data=filtered_df(),76 x=input.xvar(),77 y=input.yvar(),78 palette=palette,79 hue="Species" if input.by_species() else None,80 hue_order=species,81 legend=False,82 )83 84 @output85 @render.ui86 def value_boxes():87 df = filtered_df()88 89 def penguin_value_box(title: str, count: int, bgcol: str, showcase_img: str):90 return ui.value_box(91 title,92 count,93 {"class_": "pt-1 pb-0"},94 showcase=ui.fill.as_fill_item(95 ui.tags.img(96 {"style": "object-fit:contain;"},97 src=showcase_img,98 )99 ),100 theme_color=None,101 style=f"background-color: {bgcol};",102 )103 104 if not input.by_species():105 return penguin_value_box(106 "Penguins",107 len(df.index),108 bg_palette["default"],109 # Artwork by @allison_horst110 showcase_img="penguins.png",111 )112 113 value_boxes = [114 penguin_value_box(115 name,116 len(df[df["Species"] == name]),117 bg_palette[name],118 # Artwork by @allison_horst119 showcase_img=f"{name}.png",120 )121 for name in species122 # Only include boxes for _selected_ species123 if name in input.species()124 ]125 126 return ui.layout_column_wrap(*value_boxes, width = 1 / len(value_boxes))127 128 129# "darkorange", "purple", "cyan4"130colors = [[255, 140, 0], [160, 32, 240], [0, 139, 139]]131colors = [(r / 255.0, g / 255.0, b / 255.0) for r, g, b in colors]132 133palette: Dict[str, Tuple[float, float, float]] = {134 "Adelie": colors[0],135 "Chinstrap": colors[1],136 "Gentoo": colors[2],137 "default": sns.color_palette()[0], # type: ignore138}139 140bg_palette = {}141# Use `sns.set_style("whitegrid")` to help find approx alpha value142for name, col in palette.items():143 # Adjusted n_colors until `axe` accessibility did not complain about color contrast144 bg_palette[name] = mpl_colors.to_hex(sns.light_palette(col, n_colors=7)[1]) # type: ignore145 146 147app = App(148 app_ui,149 server,150 static_assets=str(www_dir),151)152 