import faicons as fa import plotly.express as px # Load data and compute static values from shared import app_dir, tips from shinywidgets import render_plotly from shiny import reactive, render from shiny.express import input, ui bill_rng = (min(tips.سن), max(tips.سن)) # Add page title and sidebar ui.page_opts(title="Restaurant tipping", fillable=True) with ui.sidebar(open="desktop"): ui.input_slider( "سن", "رنج سنی", min=bill_rng[0], max=bill_rng[1], value=bill_rng, pre="سال" ) ui.input_checkbox_group( "تاریخ", " service", ["Twitter", "Instagram"], selected=["Twitter", "Instagram"], inline=True, ) ui.input_action_button("reset", "Reset filter") # Add main content ICONS = { "user": fa.icon_svg("user", "regular"), "wallet": fa.icon_svg("wallet"), "currency-dollar": fa.icon_svg("dollar-sign"), "ellipsis": fa.icon_svg("ellipsis"), } with ui.layout_columns(fill=False): with ui.value_box(showcase=ICONS["user"]): "id" @render.express def total_tippers(): data = tips_data() return data.shape[0] with ui.value_box(showcase=ICONS["wallet"]): "Average tip" @render.express def average_tip(): data = tips_data() if data.shape[0] > 0: perc = data.tip / data.سن return f"{perc.mean():.1%}" with ui.value_box(showcase=ICONS["currency-dollar"]): "Average bill" @render.express def average_bill(): data = tips_data() if data.shape[0] > 0: bill = data.سن.mean() return f"${bill:.2f}" with ui.layout_columns(col_widths=[6, 6, 12]): with ui.card(full_screen=True): ui.card_header("Tips data") @render.data_frame def table(): return tips_data() # جدول با داده‌های فیلتر شده @render_plotly def scatterplot(): data = tips_data() # داده‌های فیلتر شده برای نمودار if data.shape[0] == 0: return {} # اگر هیچ داده‌ای نیست، نمودار خالی برگردانده می‌شود return px.scatter( data, x="سن", # استفاده از ستون "سن" y="id", # استفاده از ستون "id" color=None if input.scatter_color() == "none" else input.scatter_color(), # رنگ بر اساس انتخاب trendline="lowess", # اضافه کردن trendline به نمودار ) with ui.card(full_screen=True): with ui.card_header(class_="d-flex justify-content-between align-items-center"): "Tip percentages" with ui.popover(title="Add a color variable"): ICONS["ellipsis"] ui.input_radio_buttons( "tip_perc_y", "Split by:", [ "جنسیت", "تأثیر", "سطح ", "موضوع"], selected="day", inline=True, ) @render_plotly def tip_perc(): from ridgeplot import ridgeplot dat = tips_data() if dat.shape[0] == 0: return {} # return empty plot if no data available dat["percent"] = dat.tip / dat.سن yvar = input.tip_perc_y() uvals = dat[yvar].unique() samples = [[dat.percent[dat[yvar] == val]] for val in uvals] plt = ridgeplot( samples=samples, labels=uvals, bandwidth=0.01, colorscale="viridis", colormode="row-index", ) plt.update_layout( legend=dict( orientation="h", yanchor="bottom", y=1.02, xanchor="center", x=0.5 ) ) return plt ui.include_css(app_dir / "styles.css") # -------------------------------------------------------- # Reactive calculations and effects # -------------------------------------------------------- @reactive.calc def tips_data(): سنی = input.سن() # مقدار رنج سنی تاریخ_انتخابی = input.time() # تاریخ‌های انتخابی print(f"Selected age range: {سنی}") print(f"Selected dates: {تاریخ_انتخابی}") idx1 = tips["سن"].between(سنی[0], سنی[1]) # فیلتر بر اساس رنج سنی idx2 = tips["تاریخ"].isin(tاریخ_انتخابی) # فیلتر بر اساس تاریخ انتخابی filtered_data = tips[idx1 & idx2] # داده‌های فیلتر شده print(f"Filtered data: {filtered_data}") # چاپ داده‌های فیلتر شده return filtered_data @reactive.effect @reactive.event(input.reset) def _(): ui.update_slider("رنج سنی", value=bill_rng) ui.update_checkbox_group("تاریخ", selected=["Twitter", "Instagram"])