gaogao131/python_code
0
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)158 