Spaces:
Running
Running
Add Label to all charts
Browse files- streamlit_app.py +59 -2
streamlit_app.py
CHANGED
|
@@ -965,6 +965,11 @@ with tab_overview:
|
|
| 965 |
x="YearMonth", y="Revenue", color="Series",
|
| 966 |
markers=True,
|
| 967 |
color_discrete_sequence=BRAND_SEQUENCE,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 968 |
)
|
| 969 |
fig.update_yaxes(tickformat=",.0f")
|
| 970 |
fig.update_layout(xaxis_title=None, yaxis_title="Revenue (THB)")
|
|
@@ -996,7 +1001,11 @@ with tab_overview:
|
|
| 996 |
channel, names="Channel", values="Amount", hole=0.55,
|
| 997 |
color_discrete_sequence=BRAND_SEQUENCE,
|
| 998 |
)
|
| 999 |
-
fig.update_traces(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1000 |
st.plotly_chart(style_plotly(fig, height=420), use_container_width=True)
|
| 1001 |
else:
|
| 1002 |
st.info("No channel data for the current filters.")
|
|
@@ -1198,6 +1207,11 @@ with tab_summary:
|
|
| 1198 |
mf, x="YearMonth", y="Revenue", color="Branch",
|
| 1199 |
markers=True,
|
| 1200 |
color_discrete_map=BRANCH_COLOR,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1201 |
)
|
| 1202 |
fig.update_yaxes(tickformat=",.0f")
|
| 1203 |
fig.update_layout(title="Monthly Revenue (THB)",
|
|
@@ -1208,6 +1222,11 @@ with tab_summary:
|
|
| 1208 |
mf, x="YearMonth", y="Customers", color="Branch",
|
| 1209 |
markers=True,
|
| 1210 |
color_discrete_map=BRANCH_COLOR,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1211 |
)
|
| 1212 |
fig.update_yaxes(tickformat=",.0f")
|
| 1213 |
fig.update_layout(title="Monthly Customers",
|
|
@@ -1223,6 +1242,11 @@ with tab_summary:
|
|
| 1223 |
mf, x="YearMonth", y="%Cap", color="Branch",
|
| 1224 |
markers=True,
|
| 1225 |
color_discrete_map=BRANCH_COLOR,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1226 |
)
|
| 1227 |
fig.update_yaxes(ticksuffix="%")
|
| 1228 |
fig.update_layout(title="%Cap — Capacity utilised",
|
|
@@ -1234,6 +1258,11 @@ with tab_summary:
|
|
| 1234 |
mf, x="YearMonth", y="%Premium", color="Branch",
|
| 1235 |
markers=True,
|
| 1236 |
color_discrete_map=BRANCH_COLOR,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1237 |
)
|
| 1238 |
fig.update_yaxes(ticksuffix="%")
|
| 1239 |
fig.update_layout(title="%Premium — premium share of customers",
|
|
@@ -1257,6 +1286,12 @@ with tab_summary:
|
|
| 1257 |
barmode="stack",
|
| 1258 |
category_orders={"Round": round_cols},
|
| 1259 |
color_discrete_map=ROUND_COLOR,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1260 |
)
|
| 1261 |
fig.update_yaxes(tickformat=",.0f")
|
| 1262 |
fig.update_layout(title="Customers by Round (monthly)",
|
|
@@ -1545,6 +1580,11 @@ with tab_forecast:
|
|
| 1545 |
fig = px.line(
|
| 1546 |
preds, x="Date", y="Prediction", color="Branch",
|
| 1547 |
markers=True, color_discrete_map=BRANCH_COLOR,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1548 |
)
|
| 1549 |
fig.update_yaxes(tickformat=",.0f")
|
| 1550 |
fig.update_layout(title=f"Predicted Customers — next {horizon_days} days",
|
|
@@ -1576,6 +1616,12 @@ with tab_forecast:
|
|
| 1576 |
barmode="stack",
|
| 1577 |
color_discrete_map=ROUND_COLOR,
|
| 1578 |
category_orders={"RoundLabel": round_order},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1579 |
)
|
| 1580 |
fig.update_yaxes(tickformat=",.0f")
|
| 1581 |
fig.update_layout(
|
|
@@ -1606,12 +1652,18 @@ with tab_pl:
|
|
| 1606 |
)
|
| 1607 |
agg = agg.reindex(agg["Amount"].abs().sort_values(ascending=False).index).head(15)
|
| 1608 |
agg["Flow"] = np.where(agg["Amount"] >= 0, "Income", "Expense")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1609 |
fig = px.bar(
|
| 1610 |
agg.sort_values("Amount"),
|
| 1611 |
x="Amount", y=group_col, orientation="h", color="Flow",
|
| 1612 |
color_discrete_map={"Income": "#16A34A", "Expense": "#DC2626"},
|
| 1613 |
-
text=
|
| 1614 |
)
|
|
|
|
| 1615 |
fig.update_layout(yaxis_title=None, xaxis_title="Amount (THB)", showlegend=True)
|
| 1616 |
fig.update_xaxes(tickformat=",.0f")
|
| 1617 |
st.plotly_chart(style_plotly(fig, height=520), use_container_width=True)
|
|
@@ -1629,6 +1681,11 @@ with tab_pl:
|
|
| 1629 |
fig = px.line(
|
| 1630 |
ts, x="YearMonth", y="Amount", color="Restaurant",
|
| 1631 |
color_discrete_map=RESTAURANT_COLOR, markers=True,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1632 |
)
|
| 1633 |
fig.update_yaxes(tickformat=",.0f")
|
| 1634 |
st.plotly_chart(style_plotly(fig, height=400), use_container_width=True)
|
|
|
|
| 965 |
x="YearMonth", y="Revenue", color="Series",
|
| 966 |
markers=True,
|
| 967 |
color_discrete_sequence=BRAND_SEQUENCE,
|
| 968 |
+
text="Revenue",
|
| 969 |
+
)
|
| 970 |
+
fig.update_traces(
|
| 971 |
+
texttemplate="฿%{y:,.0f}", textposition="top center",
|
| 972 |
+
textfont=dict(size=10),
|
| 973 |
)
|
| 974 |
fig.update_yaxes(tickformat=",.0f")
|
| 975 |
fig.update_layout(xaxis_title=None, yaxis_title="Revenue (THB)")
|
|
|
|
| 1001 |
channel, names="Channel", values="Amount", hole=0.55,
|
| 1002 |
color_discrete_sequence=BRAND_SEQUENCE,
|
| 1003 |
)
|
| 1004 |
+
fig.update_traces(
|
| 1005 |
+
textposition="inside",
|
| 1006 |
+
texttemplate="%{label}<br>฿%{value:,.0f}<br>%{percent}",
|
| 1007 |
+
insidetextfont=dict(size=11),
|
| 1008 |
+
)
|
| 1009 |
st.plotly_chart(style_plotly(fig, height=420), use_container_width=True)
|
| 1010 |
else:
|
| 1011 |
st.info("No channel data for the current filters.")
|
|
|
|
| 1207 |
mf, x="YearMonth", y="Revenue", color="Branch",
|
| 1208 |
markers=True,
|
| 1209 |
color_discrete_map=BRANCH_COLOR,
|
| 1210 |
+
text="Revenue",
|
| 1211 |
+
)
|
| 1212 |
+
fig.update_traces(
|
| 1213 |
+
texttemplate="฿%{y:,.0f}", textposition="top center",
|
| 1214 |
+
textfont=dict(size=9),
|
| 1215 |
)
|
| 1216 |
fig.update_yaxes(tickformat=",.0f")
|
| 1217 |
fig.update_layout(title="Monthly Revenue (THB)",
|
|
|
|
| 1222 |
mf, x="YearMonth", y="Customers", color="Branch",
|
| 1223 |
markers=True,
|
| 1224 |
color_discrete_map=BRANCH_COLOR,
|
| 1225 |
+
text="Customers",
|
| 1226 |
+
)
|
| 1227 |
+
fig.update_traces(
|
| 1228 |
+
texttemplate="%{y:,.0f}", textposition="top center",
|
| 1229 |
+
textfont=dict(size=9),
|
| 1230 |
)
|
| 1231 |
fig.update_yaxes(tickformat=",.0f")
|
| 1232 |
fig.update_layout(title="Monthly Customers",
|
|
|
|
| 1242 |
mf, x="YearMonth", y="%Cap", color="Branch",
|
| 1243 |
markers=True,
|
| 1244 |
color_discrete_map=BRANCH_COLOR,
|
| 1245 |
+
text="%Cap",
|
| 1246 |
+
)
|
| 1247 |
+
fig.update_traces(
|
| 1248 |
+
texttemplate="%{y:.1f}%", textposition="top center",
|
| 1249 |
+
textfont=dict(size=9),
|
| 1250 |
)
|
| 1251 |
fig.update_yaxes(ticksuffix="%")
|
| 1252 |
fig.update_layout(title="%Cap — Capacity utilised",
|
|
|
|
| 1258 |
mf, x="YearMonth", y="%Premium", color="Branch",
|
| 1259 |
markers=True,
|
| 1260 |
color_discrete_map=BRANCH_COLOR,
|
| 1261 |
+
text="%Premium",
|
| 1262 |
+
)
|
| 1263 |
+
fig.update_traces(
|
| 1264 |
+
texttemplate="%{y:.1f}%", textposition="top center",
|
| 1265 |
+
textfont=dict(size=9),
|
| 1266 |
)
|
| 1267 |
fig.update_yaxes(ticksuffix="%")
|
| 1268 |
fig.update_layout(title="%Premium — premium share of customers",
|
|
|
|
| 1286 |
barmode="stack",
|
| 1287 |
category_orders={"Round": round_cols},
|
| 1288 |
color_discrete_map=ROUND_COLOR,
|
| 1289 |
+
text="Customers",
|
| 1290 |
+
)
|
| 1291 |
+
fig.update_traces(
|
| 1292 |
+
texttemplate="%{y:,.0f}", textposition="inside",
|
| 1293 |
+
textfont=dict(size=10, color="#FAF7F2"),
|
| 1294 |
+
insidetextanchor="middle",
|
| 1295 |
)
|
| 1296 |
fig.update_yaxes(tickformat=",.0f")
|
| 1297 |
fig.update_layout(title="Customers by Round (monthly)",
|
|
|
|
| 1580 |
fig = px.line(
|
| 1581 |
preds, x="Date", y="Prediction", color="Branch",
|
| 1582 |
markers=True, color_discrete_map=BRANCH_COLOR,
|
| 1583 |
+
text="Prediction",
|
| 1584 |
+
)
|
| 1585 |
+
fig.update_traces(
|
| 1586 |
+
texttemplate="%{y:,.0f}", textposition="top center",
|
| 1587 |
+
textfont=dict(size=9),
|
| 1588 |
)
|
| 1589 |
fig.update_yaxes(tickformat=",.0f")
|
| 1590 |
fig.update_layout(title=f"Predicted Customers — next {horizon_days} days",
|
|
|
|
| 1616 |
barmode="stack",
|
| 1617 |
color_discrete_map=ROUND_COLOR,
|
| 1618 |
category_orders={"RoundLabel": round_order},
|
| 1619 |
+
text="Total_Seats",
|
| 1620 |
+
)
|
| 1621 |
+
fig.update_traces(
|
| 1622 |
+
texttemplate="%{y:,.0f}", textposition="inside",
|
| 1623 |
+
textfont=dict(size=10, color="#FAF7F2"),
|
| 1624 |
+
insidetextanchor="middle",
|
| 1625 |
)
|
| 1626 |
fig.update_yaxes(tickformat=",.0f")
|
| 1627 |
fig.update_layout(
|
|
|
|
| 1652 |
)
|
| 1653 |
agg = agg.reindex(agg["Amount"].abs().sort_values(ascending=False).index).head(15)
|
| 1654 |
agg["Flow"] = np.where(agg["Amount"] >= 0, "Income", "Expense")
|
| 1655 |
+
# Pre-format the label as a column so it travels with the row when
|
| 1656 |
+
# we sort below — the previous version computed `text` against the
|
| 1657 |
+
# original DataFrame and then passed a re-sorted one to px.bar,
|
| 1658 |
+
# so labels ended up paired with the wrong bars.
|
| 1659 |
+
agg["AmountLabel"] = agg["Amount"].apply(fmt_money)
|
| 1660 |
fig = px.bar(
|
| 1661 |
agg.sort_values("Amount"),
|
| 1662 |
x="Amount", y=group_col, orientation="h", color="Flow",
|
| 1663 |
color_discrete_map={"Income": "#16A34A", "Expense": "#DC2626"},
|
| 1664 |
+
text="AmountLabel",
|
| 1665 |
)
|
| 1666 |
+
fig.update_traces(textposition="outside", cliponaxis=False)
|
| 1667 |
fig.update_layout(yaxis_title=None, xaxis_title="Amount (THB)", showlegend=True)
|
| 1668 |
fig.update_xaxes(tickformat=",.0f")
|
| 1669 |
st.plotly_chart(style_plotly(fig, height=520), use_container_width=True)
|
|
|
|
| 1681 |
fig = px.line(
|
| 1682 |
ts, x="YearMonth", y="Amount", color="Restaurant",
|
| 1683 |
color_discrete_map=RESTAURANT_COLOR, markers=True,
|
| 1684 |
+
text="Amount",
|
| 1685 |
+
)
|
| 1686 |
+
fig.update_traces(
|
| 1687 |
+
texttemplate="฿%{y:,.0f}", textposition="top center",
|
| 1688 |
+
textfont=dict(size=9),
|
| 1689 |
)
|
| 1690 |
fig.update_yaxes(tickformat=",.0f")
|
| 1691 |
st.plotly_chart(style_plotly(fig, height=400), use_container_width=True)
|