mathiassandnes Claude Opus 4.5 commited on
Commit
ece90cc
·
1 Parent(s): 15d717a

Fix: use_column_width for older Streamlit on HF

Browse files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +13 -13
app.py CHANGED
@@ -101,7 +101,7 @@ selected_product = st.sidebar.selectbox(
101
  config = products[selected_product]
102
 
103
  if "image_url" in products[selected_product].get("product", {}):
104
- st.sidebar.image(products[selected_product]["product"]["image_url"], use_container_width=True)
105
 
106
  st.sidebar.markdown("---")
107
  st.sidebar.header("View")
@@ -490,7 +490,7 @@ if selected_view == "Strategy":
490
  xaxis_title="Months", yaxis_title="Cumulative Profit (NOK)",
491
  showlegend=False, yaxis=dict(separatethousands=True),
492
  )
493
- st.plotly_chart(fig_be, use_container_width=True)
494
 
495
  st.markdown("---")
496
 
@@ -543,7 +543,7 @@ if selected_view == "Strategy":
543
  yaxis_title="NOK", showlegend=False,
544
  yaxis=dict(separatethousands=True),
545
  )
546
- st.plotly_chart(fig_rc, use_container_width=True)
547
 
548
  mfg_share = s_mfg_cost / reuse_cycles if reuse_cycles > 0 else s_mfg_cost
549
  st.caption(f"Blended cost breakdown: Mfg share {sfmt(mfg_share)} + logistics {sfmt(logistics_per_cycle)} + repair {sfmt(repair_per_cycle)} = **{sfmt(blended_cost_per_product)} NOK** per product per cycle")
@@ -622,7 +622,7 @@ if selected_view == "Strategy":
622
  xaxis_title="Months", yaxis_title="Cumulative Profit (NOK)",
623
  showlegend=False, yaxis=dict(separatethousands=True),
624
  )
625
- st.plotly_chart(fig_trajectory, use_container_width=True)
626
 
627
  final_profit = cumulative_profit[-1]
628
  st.caption(f"5-year projection with {sfmt(fleet_needed)} unit fleet. Final cumulative profit: **{sfmt(final_profit)} NOK**")
@@ -662,7 +662,7 @@ if selected_view == "Strategy":
662
  yaxis=dict(separatethousands=True, rangemode="tozero"),
663
  legend=dict(orientation="h", yanchor="bottom", y=1.02),
664
  )
665
- st.plotly_chart(fig_fleet, use_container_width=True)
666
  savings = customers_served[-1] - portfolio_size
667
  st.caption(f"{sfmt(portfolio_size)} products serve **{sfmt(customers_served[-1])} families** over {reuse_cycles} cycles — **{sfmt(savings)} fewer products** manufactured vs linear model.")
668
 
@@ -705,7 +705,7 @@ elif selected_view == "Design":
705
  )
706
  fig_grades.update_traces(texttemplate='%{text:.0f}%', textposition='outside')
707
  fig_grades.update_layout(showlegend=False, yaxis_title="% of Returns")
708
- st.plotly_chart(fig_grades, use_container_width=True)
709
 
710
  st.info(f"**Design insight:** Reducing repair rate from {grade_b_pct:.0%} to {max(5, grade_b_pct*100-10):.0f}% would save €{(grade_b_pct - max(0.05, grade_b_pct-0.10)) * refurb_b:.0f} per returned product.")
711
 
@@ -758,7 +758,7 @@ elif selected_view == "Design":
758
  yaxis_title="Material Composition (%)", yaxis_range=[0, 120],
759
  legend=dict(orientation="h", yanchor="bottom", y=1.02),
760
  )
761
- st.plotly_chart(fig_materials, use_container_width=True)
762
 
763
  final_original = lifecycle_df.iloc[-1]["Original Material %"]
764
  final_new = lifecycle_df.iloc[-1]["New Parts Added %"]
@@ -805,7 +805,7 @@ elif selected_view == "Logistics":
805
  )
806
  fig_grades.update_traces(texttemplate='%{text:.0f}%', textposition='outside')
807
  fig_grades.update_layout(showlegend=False, yaxis_title="% of Returns")
808
- st.plotly_chart(fig_grades, use_container_width=True)
809
 
810
  with grade_col2:
811
  st.subheader("Cost per Cycle")
@@ -827,7 +827,7 @@ elif selected_view == "Logistics":
827
  fig_cycle.add_trace(go.Bar(name="Logistics", x=df_cycle_costs["Cycle"], y=df_cycle_costs["Logistics"],
828
  marker_color=COLORS["secondary"], text=[f"€{v:.0f}" for v in df_cycle_costs["Logistics"]], textposition="inside"))
829
  fig_cycle.update_layout(barmode="stack", yaxis_title="Cost (EUR)", legend=dict(orientation="h", yanchor="bottom", y=1.02))
830
- st.plotly_chart(fig_cycle, use_container_width=True)
831
 
832
  st.markdown(f"**Key insight:** Cycle 1 costs **€{new_unit_cost:.0f}**. Cycles 2+ cost **€{refurb_unit_cost:.0f}** ({(1-refurb_unit_cost/new_unit_cost)*100:.0f}% reduction)")
833
 
@@ -875,7 +875,7 @@ elif selected_view == "Logistics":
875
  xaxis_title="",
876
  legend=dict(orientation="h", yanchor="bottom", y=1.02),
877
  )
878
- st.plotly_chart(fig_products, use_container_width=True)
879
 
880
  final_in_service = lifecycle_df.iloc[-1]["Products in Service"]
881
  final_lost = lifecycle_df.iloc[-1]["Products Lost"]
@@ -974,7 +974,7 @@ elif selected_view == "Sourcing":
974
  totals={"marker": {"color": COLORS["info"]}},
975
  ))
976
  fig_waterfall.update_layout(title=f"Manufacturing Cost: €{mfg_cost:.0f}", yaxis_title="EUR", showlegend=False)
977
- st.plotly_chart(fig_waterfall, use_container_width=True)
978
 
979
  with cost_col2:
980
  st.subheader("Bill of Materials")
@@ -982,7 +982,7 @@ elif selected_view == "Sourcing":
982
  st.dataframe(mat_df.style.format({
983
  "Weight (kg)": "{:.1f}", "Cost/kg": "€{:.2f}",
984
  "Total Cost": "€{:.2f}", "Recycled %": "{:.0f}%",
985
- }), use_container_width=True, hide_index=True)
986
 
987
  # Summary
988
  recyclable_weight = sum(m["Weight (kg)"] for m in material_data if m["Recyclable"] == "Yes")
@@ -1092,7 +1092,7 @@ elif selected_view == "Market":
1092
  ))
1093
  fig_customer.update_layout(title="Customer Cost vs Retail Price", xaxis_title="Monthly Lease Price (EUR)",
1094
  yaxis_title="Total Customer Cost (EUR)")
1095
- st.plotly_chart(fig_customer, use_container_width=True)
1096
 
1097
  if retail_price > 0 and total_lease_cost < retail_price:
1098
  st.success(f"At €{lease_price}/mo, customers **save €{retail_price - total_lease_cost}** ({(retail_price - total_lease_cost)/retail_price*100:.0f}% less than buying)")
 
101
  config = products[selected_product]
102
 
103
  if "image_url" in products[selected_product].get("product", {}):
104
+ st.sidebar.image(products[selected_product]["product"]["image_url"], use_column_width=True)
105
 
106
  st.sidebar.markdown("---")
107
  st.sidebar.header("View")
 
490
  xaxis_title="Months", yaxis_title="Cumulative Profit (NOK)",
491
  showlegend=False, yaxis=dict(separatethousands=True),
492
  )
493
+ st.plotly_chart(fig_be, use_column_width=True)
494
 
495
  st.markdown("---")
496
 
 
543
  yaxis_title="NOK", showlegend=False,
544
  yaxis=dict(separatethousands=True),
545
  )
546
+ st.plotly_chart(fig_rc, use_column_width=True)
547
 
548
  mfg_share = s_mfg_cost / reuse_cycles if reuse_cycles > 0 else s_mfg_cost
549
  st.caption(f"Blended cost breakdown: Mfg share {sfmt(mfg_share)} + logistics {sfmt(logistics_per_cycle)} + repair {sfmt(repair_per_cycle)} = **{sfmt(blended_cost_per_product)} NOK** per product per cycle")
 
622
  xaxis_title="Months", yaxis_title="Cumulative Profit (NOK)",
623
  showlegend=False, yaxis=dict(separatethousands=True),
624
  )
625
+ st.plotly_chart(fig_trajectory, use_column_width=True)
626
 
627
  final_profit = cumulative_profit[-1]
628
  st.caption(f"5-year projection with {sfmt(fleet_needed)} unit fleet. Final cumulative profit: **{sfmt(final_profit)} NOK**")
 
662
  yaxis=dict(separatethousands=True, rangemode="tozero"),
663
  legend=dict(orientation="h", yanchor="bottom", y=1.02),
664
  )
665
+ st.plotly_chart(fig_fleet, use_column_width=True)
666
  savings = customers_served[-1] - portfolio_size
667
  st.caption(f"{sfmt(portfolio_size)} products serve **{sfmt(customers_served[-1])} families** over {reuse_cycles} cycles — **{sfmt(savings)} fewer products** manufactured vs linear model.")
668
 
 
705
  )
706
  fig_grades.update_traces(texttemplate='%{text:.0f}%', textposition='outside')
707
  fig_grades.update_layout(showlegend=False, yaxis_title="% of Returns")
708
+ st.plotly_chart(fig_grades, use_column_width=True)
709
 
710
  st.info(f"**Design insight:** Reducing repair rate from {grade_b_pct:.0%} to {max(5, grade_b_pct*100-10):.0f}% would save €{(grade_b_pct - max(0.05, grade_b_pct-0.10)) * refurb_b:.0f} per returned product.")
711
 
 
758
  yaxis_title="Material Composition (%)", yaxis_range=[0, 120],
759
  legend=dict(orientation="h", yanchor="bottom", y=1.02),
760
  )
761
+ st.plotly_chart(fig_materials, use_column_width=True)
762
 
763
  final_original = lifecycle_df.iloc[-1]["Original Material %"]
764
  final_new = lifecycle_df.iloc[-1]["New Parts Added %"]
 
805
  )
806
  fig_grades.update_traces(texttemplate='%{text:.0f}%', textposition='outside')
807
  fig_grades.update_layout(showlegend=False, yaxis_title="% of Returns")
808
+ st.plotly_chart(fig_grades, use_column_width=True)
809
 
810
  with grade_col2:
811
  st.subheader("Cost per Cycle")
 
827
  fig_cycle.add_trace(go.Bar(name="Logistics", x=df_cycle_costs["Cycle"], y=df_cycle_costs["Logistics"],
828
  marker_color=COLORS["secondary"], text=[f"€{v:.0f}" for v in df_cycle_costs["Logistics"]], textposition="inside"))
829
  fig_cycle.update_layout(barmode="stack", yaxis_title="Cost (EUR)", legend=dict(orientation="h", yanchor="bottom", y=1.02))
830
+ st.plotly_chart(fig_cycle, use_column_width=True)
831
 
832
  st.markdown(f"**Key insight:** Cycle 1 costs **€{new_unit_cost:.0f}**. Cycles 2+ cost **€{refurb_unit_cost:.0f}** ({(1-refurb_unit_cost/new_unit_cost)*100:.0f}% reduction)")
833
 
 
875
  xaxis_title="",
876
  legend=dict(orientation="h", yanchor="bottom", y=1.02),
877
  )
878
+ st.plotly_chart(fig_products, use_column_width=True)
879
 
880
  final_in_service = lifecycle_df.iloc[-1]["Products in Service"]
881
  final_lost = lifecycle_df.iloc[-1]["Products Lost"]
 
974
  totals={"marker": {"color": COLORS["info"]}},
975
  ))
976
  fig_waterfall.update_layout(title=f"Manufacturing Cost: €{mfg_cost:.0f}", yaxis_title="EUR", showlegend=False)
977
+ st.plotly_chart(fig_waterfall, use_column_width=True)
978
 
979
  with cost_col2:
980
  st.subheader("Bill of Materials")
 
982
  st.dataframe(mat_df.style.format({
983
  "Weight (kg)": "{:.1f}", "Cost/kg": "€{:.2f}",
984
  "Total Cost": "€{:.2f}", "Recycled %": "{:.0f}%",
985
+ }), use_column_width=True, hide_index=True)
986
 
987
  # Summary
988
  recyclable_weight = sum(m["Weight (kg)"] for m in material_data if m["Recyclable"] == "Yes")
 
1092
  ))
1093
  fig_customer.update_layout(title="Customer Cost vs Retail Price", xaxis_title="Monthly Lease Price (EUR)",
1094
  yaxis_title="Total Customer Cost (EUR)")
1095
+ st.plotly_chart(fig_customer, use_column_width=True)
1096
 
1097
  if retail_price > 0 and total_lease_cost < retail_price:
1098
  st.success(f"At €{lease_price}/mo, customers **save €{retail_price - total_lease_cost}** ({(retail_price - total_lease_cost)/retail_price*100:.0f}% less than buying)")