File size: 4,978 Bytes
7273765 f48c224 7273765 f48c224 dec834f 7273765 0e6c12e dec834f 7273765 16f58d4 f48c224 7273765 0bc57e9 7273765 8398c29 7273765 8398c29 7273765 8398c29 7273765 f48c224 7273765 8398c29 7273765 8398c29 38abfed 7273765 f48c224 7273765 8398c29 38abfed 7273765 0bc57e9 8398c29 16f58d4 8398c29 7273765 0bc57e9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
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 render.DataGrid(tips_data())
with ui.card(full_screen=True):
with ui.card_header(class_="d-flex justify-content-between align-items-center"):
"Total bill vs tip"
with ui.popover(title="Add a color variable", placement="top"):
ICONS["ellipsis"]
ui.input_radio_buttons(
"scatter_color",
None,
["none", "جنسیت", "تأثیر", "سطح ", "موضوع"],
inline=True,
)
@render_plotly
def scatterplot():
color = input.scatter_color()
data = tips_data()
if data.shape[0] == 0:
return {} # return empty plot if no data available
return px.scatter(
data,
x="سن",
y="id",
color=None if color == "none" else color,
trendline="lowess",
)
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.سن()
idx1 = tips.سن.between(سنی[0], سنی[1]) # Corrected range filter
idx2 = tips.تاریخ.isin(input.time()) # Filter based on selected time (Twitter, Instagram)
return tips[idx1 & idx2] # Apply filters to the tips data
@reactive.effect
@reactive.event(input.reset)
def _():
ui.update_slider("رنج سنی", value=bill_rng)
ui.update_checkbox_group("تاریخ", selected=["Twitter", "Instagram"]) |