Yield-predictor / app.py
Ayesha-Majeed's picture
Update app.py
e6daf44 verified
import gradio as gr
import pandas as pd
import numpy as np
import joblib
# -----------------------------
# 1️⃣ Load model and data
# -----------------------------
MODEL_PATH = "linear_model.pkl"
EXCEL_PATH = "excel sheet of plant 2.xlsx"
linear_model = joblib.load(MODEL_PATH)
df = pd.read_excel(EXCEL_PATH)
df.columns = df.columns.str.strip()
# Strains and rows
strain_names = df['pea plant strain'].unique().tolist()
row_options = ["None, Enter Manually"] + [str(i) for i in range(len(df))]
#-------------- To be commented --------------------
# -----------------------------
# 2️⃣ Autofill function
# -----------------------------
# def autofill_fields(row_index):
# if row_index == "None, Enter Manually":
# return [None]*11
# row = df.iloc[int(row_index)]
# return (
# row['Dose (g/pot)'], row['Soil N (ppm)'], row['Soil P (ppm)'],
# row['Soil K (ppm)'], row['pH'], row['Chlorophyll (SPAD)'],
# row['Shoot Length (cm)'], row['Root Length (cm)'], row['Shoot Wt (g)'],
# row['Root Wt (g)'], row['Yield (g/pot)']
# )
# -----------------------------
# 3️⃣ Prediction function
# -----------------------------
def predict_linear(strain, dose, soil_n, soil_p, soil_k, ph,
chlorophyll, shoot_len, root_len, shoot_wt, root_wt, yield_gp):
logs = []
# -----------------------------
# 🧩 Convert textbox inputs to floats (or None if blank)
# -----------------------------
# def to_float(x):
# try:
# return float(x)
# except (TypeError, ValueError):
# return None
# dose = to_float(dose)
# soil_n = to_float(soil_n)
# soil_p = to_float(soil_p)
# soil_k = to_float(soil_k)
# ph = to_float(ph)
# # -----------------------------
required = [dose, soil_n, soil_p, soil_k, ph]
if any(v is None for v in required):
logs.append("[DEBUG] Missing numeric inputs!")
return pd.DataFrame(), "\n⚠️ Fill all required inputs", "\n".join(logs)
logs.append("[DEBUG] Inputs received.")
# Prepare DataFrame for model
X_input = pd.DataFrame([{
'pea plant strain': strain,
'Dose (g/pot)': dose,
'Soil N (ppm)': soil_n,
'Soil P (ppm)': soil_p,
'Soil K (ppm)': soil_k,
'pH': ph
}])
logs.append(f"[DEBUG] Input DataFrame:\n{X_input}")
y_pred = linear_model.predict(X_input)[0]
logs.append(f"[DEBUG] Predicted values:\n{y_pred}")
# Actuals and errors
actuals = [chlorophyll, shoot_len, root_len, shoot_wt, root_wt, yield_gp]
abs_errors = [
round(abs(p - a), 2) if a is not None else "N/A"
for p, a in zip(y_pred[:6], actuals)
]
target_cols = ['Chlorophyll (SPAD)', 'Shoot Length (cm)', 'Root Length (cm)',
'Shoot Wt (g)', 'Root Wt (g)', 'Yield (g/pot)', 'Relative Yield (%)']
# Build table DataFrame
data = {
"Output Metric": target_cols,
# "Actual Value": actuals + ["N/A"],
"Predicted Value": [round(v, 2) for v in y_pred],
# "Absolute Error": abs_errors + ["N/A"]
}
result_df = pd.DataFrame(data)
return result_df, "Prediction complete!", "\n".join(logs)
# -----------------------------
# Clear Inputs Function
# -----------------------------
def clear_inputs():
# Reset all input fields to None
return [None] * 11 # same number of numeric input fields
# -----------------------------
# 4️⃣ Gradio Interface (Green Theme)
# -----------------------------
invalid_strains = ["Strains", "strain1", "strain2", ""]
valid_strain = next(
(s for s in strain_names if pd.notna(s) and s not in invalid_strains),
strain_names[0]
)
with gr.Blocks(
title="Linear Regression Plant Predictor",
theme=gr.themes.Soft(
primary_hue="green",
secondary_hue="green",
neutral_hue="green"
)
) as demo:
gr.Markdown("<h1 style='text-align:center; color:#2E8B57;'>Linear Regression, Plant Yield Predictor</h1>")
strain_names = ["Tetradesmus nigardi", "Clostroprosis acicularis"]
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### Plant & Strain")
strain_input = gr.Dropdown(
strain_names,
label="Select Strain",
value=strain_names[0] # default: Tetradesmus nigardi
)
# row_selector = gr.Dropdown(row_options, label="Select Row", value="None, Enter Manually")
gr.Markdown("### Input Parameters")
dose = gr.Number(label="Dose (g/pot)",placeholder="Enter value") # ,placeholder="Enter value"
soil_n = gr.Number(label="Soil N (ppm)",placeholder="Enter value")
soil_p = gr.Number(label="Soil P (ppm)",placeholder="Enter value")
soil_k = gr.Number(label="Soil K (ppm)",placeholder="Enter value")
ph = gr.Number(label="pH")
# gr.Markdown("### Autofilled Actual Metrics (from Excel)")
# chlorophyll = gr.Number(label="Chlorophyll (SPAD)")
# shoot_len = gr.Number(label="Shoot Length (cm)")
# root_len = gr.Number(label="Root Length (cm)")
# shoot_wt = gr.Number(label="Shoot Wt (g)")
# root_wt = gr.Number(label="Root Wt (g)")
# yield_gp = gr.Number(label="Yield (g/pot)")
# Hidden placeholders for metrics
chlorophyll = gr.State(None)
shoot_len = gr.State(None)
root_len = gr.State(None)
shoot_wt = gr.State(None)
root_wt = gr.State(None)
yield_gp = gr.State(None)
with gr.Row():
predict_btn = gr.Button(" Predict", variant="primary")
clear_btn = gr.Button("🧹 Clear Inputs", variant="secondary")
with gr.Column(scale=1):
gr.Markdown("### Prediction Results Table")
result_table = gr.DataFrame(
headers=["Output Metric", "Predicted Value"], #"Actual Value", "Absolute Error"
label="Results Comparison",
interactive=False
)
status_box = gr.Markdown("")
log_box = gr.Textbox(label="Debug Logs", lines=15)
gr.Markdown(
"""
### Input Tips:
- Select the **plant strain** you want to analyze.
- Provide all essential input parameters: **Dose (g/pot), Soil N, Soil P, Soil K, and pH**.
- Click **“Predict”** to generate the model’s predictions.
### Output Tips:
<div>
<p style="margin:6px 0;"><strong>Prediction Table:</strong> Displays model predictions for all plant growth metrics.</p>
<p style="margin:6px 0;"><strong>Debug Logs:</strong> Provides detailed trace of model inputs and internal calculations.</p>
</div>
"""
)
# #Autofill callback
# row_selector.change(
# fn=autofill_fields,
# inputs=[row_selector],
# outputs=[dose, soil_n, soil_p, soil_k, ph,
# chlorophyll, shoot_len, root_len,
# shoot_wt, root_wt, yield_gp]
# )
# Prediction callback
predict_btn.click(
fn=predict_linear,
inputs=[strain_input, dose, soil_n, soil_p, soil_k, ph,
chlorophyll, shoot_len, root_len, shoot_wt, root_wt, yield_gp],
outputs=[result_table, status_box, log_box]
)
# Clear button callback
clear_btn.click(
fn=clear_inputs,
inputs=[],
outputs=[dose, soil_n, soil_p, soil_k, ph,
chlorophyll, shoot_len, root_len,
shoot_wt, root_wt, yield_gp]
)
# -----------------------------
# 5️⃣ Launch
# -----------------------------
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)