feat: add multi animals to a data frame and clear functionality
Browse files- app/assets/config/config_df.json +19 -0
- app/behavior_checkbox.py +5 -0
- app/dead.py +2 -2
- app/main_multianimal.py +56 -37
- app/physical_checkbox.py +5 -1
- app/utils_df.py +38 -0
- app/utils_json.py +6 -1
- app/wounded.py +2 -2
app/assets/config/config_df.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"headers": [
|
| 3 |
+
"image",
|
| 4 |
+
"latitude",
|
| 5 |
+
"longitude",
|
| 6 |
+
"wounded",
|
| 7 |
+
"dead",
|
| 8 |
+
"circumstance",
|
| 9 |
+
"circumstance_dropdown_level1",
|
| 10 |
+
"circumstance_dropdown_level2",
|
| 11 |
+
"circumstance_openfield_level2",
|
| 12 |
+
"circumstance_dropdown_extra_level2",
|
| 13 |
+
"physical_changes_beak",
|
| 14 |
+
"physical_changes_body",
|
| 15 |
+
"physical_changes_head",
|
| 16 |
+
"physical_changes_feathers",
|
| 17 |
+
"physical_changes_legs"
|
| 18 |
+
]
|
| 19 |
+
}
|
app/behavior_checkbox.py
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
|
|
| 1 |
from utils_config import get_custom_config_dropdowns
|
| 2 |
from utils_checkbox import create_checkbox
|
| 3 |
from utils_visible import set_visible
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
def retrieve_behavior_options_description():
|
| 6 |
dropdown_config = get_custom_config_dropdowns("config_checkbox_behavior.json")
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
from utils_config import get_custom_config_dropdowns
|
| 3 |
from utils_checkbox import create_checkbox
|
| 4 |
from utils_visible import set_visible
|
| 5 |
+
from utils_json import add_data_to_individual
|
| 6 |
+
|
| 7 |
+
def on_select_behavior(behavior_checkbox):
|
| 8 |
+
add_data_to_individual("behavior", behavior_checkbox)
|
| 9 |
|
| 10 |
def retrieve_behavior_options_description():
|
| 11 |
dropdown_config = get_custom_config_dropdowns("config_checkbox_behavior.json")
|
app/dead.py
CHANGED
|
@@ -6,8 +6,8 @@ from utils_json import add_data_to_individual
|
|
| 6 |
def show_section_dead(visible):
|
| 7 |
if visible==True:
|
| 8 |
add_data_to_individual("dead", "True")
|
| 9 |
-
|
| 10 |
-
|
| 11 |
with gr.Column(visible=visible, elem_id="dead") as section_dead:
|
| 12 |
gr.Markdown("# Dead Animal")
|
| 13 |
gr.Markdown("## Please describe the cause of death", label="description")
|
|
|
|
| 6 |
def show_section_dead(visible):
|
| 7 |
if visible==True:
|
| 8 |
add_data_to_individual("dead", "True")
|
| 9 |
+
add_data_to_individual("wounded", "False")
|
| 10 |
+
|
| 11 |
with gr.Column(visible=visible, elem_id="dead") as section_dead:
|
| 12 |
gr.Markdown("# Dead Animal")
|
| 13 |
gr.Markdown("## Please describe the cause of death", label="description")
|
app/main_multianimal.py
CHANGED
|
@@ -1,36 +1,26 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
from gradio_modal import Modal
|
| 3 |
-
import numpy as np
|
| 4 |
|
|
|
|
| 5 |
from utils_json import *
|
|
|
|
|
|
|
| 6 |
from functools import partial
|
| 7 |
from dead import show_section_dead
|
| 8 |
from wounded import show_section_wounded
|
| 9 |
from circumstances import show_causes
|
| 10 |
from circumstances_dropdowns import *
|
| 11 |
from physical_select_animal import show_physical, find_bounding_box
|
| 12 |
-
from
|
| 13 |
-
from
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
def save_input(input, df):
|
| 17 |
-
#input_value = str(input)
|
| 18 |
-
df_values = np.array(df) # handle empty dataframe case
|
| 19 |
-
new_row = [input, 0, input] # default 'age' as 0 for now
|
| 20 |
-
df_values = np.vstack([df_values, new_row])
|
| 21 |
-
df = gr.DataFrame(value=df_values)
|
| 22 |
-
return df
|
| 23 |
|
| 24 |
-
with gr.Blocks() as demo:
|
| 25 |
# with gr.Tab("Tab 1"):
|
| 26 |
-
|
| 27 |
-
df = gr.Dataframe(
|
| 28 |
-
|
| 29 |
-
#datatype=["str", "number", "str"],
|
| 30 |
-
row_count=1,
|
| 31 |
-
#col_count=(3, "fixed"),
|
| 32 |
-
)
|
| 33 |
-
show_markdown = gr.Markdown("This is a markdown")
|
| 34 |
with Modal(visible=False) as modal:
|
| 35 |
# ---------------------------------------------------------
|
| 36 |
# Intro Text
|
|
@@ -54,13 +44,15 @@ with gr.Blocks() as demo:
|
|
| 54 |
identified_location= gr.Textbox(visible=False, interactive=False,
|
| 55 |
label="Identified GPS Location")
|
| 56 |
with gr.Row():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
#to clear it
|
| 58 |
-
clear_location = gr.ClearButton(components=[location
|
|
|
|
| 59 |
)
|
| 60 |
clear_location.click()
|
| 61 |
-
#to submit it
|
| 62 |
-
submit_location = gr.Button("Get GPS Coordinates", visible=True, interactive=True, scale=3)
|
| 63 |
-
submit_location.click(get_location, inputs=[location], outputs=[identified_location])
|
| 64 |
|
| 65 |
# ---------------------------------------------------------
|
| 66 |
# ---------------------------------------------------------
|
|
@@ -89,7 +81,7 @@ with gr.Blocks() as demo:
|
|
| 89 |
|
| 90 |
# ---------------------------------------------------------
|
| 91 |
# ---------------------------------------------------------
|
| 92 |
-
|
| 93 |
# Dead Button Logic
|
| 94 |
partial_show_section_dead = partial(show_section_dead, True)
|
| 95 |
partial_hide_section_wounded = partial(show_section_wounded, False)
|
|
@@ -137,7 +129,9 @@ with gr.Blocks() as demo:
|
|
| 137 |
button_natural_cause_dead.click(dropdown_natural_cause, outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
| 138 |
|
| 139 |
dropdown_dead.select(on_select, None, [dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
| 140 |
-
|
|
|
|
|
|
|
| 141 |
# ---------------------------------------------------------
|
| 142 |
# Radio Cause Wounded
|
| 143 |
radio_cause_wounded.change(fn=show_causes,
|
|
@@ -162,7 +156,8 @@ with gr.Blocks() as demo:
|
|
| 162 |
radio_behavior_wounded.change(fn=show_behavior,
|
| 163 |
inputs=[radio_behavior_wounded, gr.Text("wounded", visible=False)],
|
| 164 |
outputs=[behavior_checkbox, behavior_text])
|
| 165 |
-
|
|
|
|
| 166 |
# ---------------------------------------------------------
|
| 167 |
# Radio Physical Wounded
|
| 168 |
radio_physical_wounded.change(fn=show_physical,
|
|
@@ -172,17 +167,41 @@ with gr.Blocks() as demo:
|
|
| 172 |
# Checkbox Physical Wounded
|
| 173 |
physical_boxes_wounded.select(find_bounding_box,
|
| 174 |
inputs=[physical_boxes_wounded, gr.Textbox(value="wounded", visible=False)],
|
| 175 |
-
outputs=[checkbox_beak, text_beak,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 176 |
])
|
| 177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
|
| 179 |
-
|
| 180 |
-
#
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
|
| 187 |
|
| 188 |
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from gradio_modal import Modal
|
|
|
|
| 3 |
|
| 4 |
+
from utils_df import get_headers
|
| 5 |
from utils_json import *
|
| 6 |
+
from utils_df import save_individual_to_df, get_headers
|
| 7 |
+
from maps import get_location
|
| 8 |
from functools import partial
|
| 9 |
from dead import show_section_dead
|
| 10 |
from wounded import show_section_wounded
|
| 11 |
from circumstances import show_causes
|
| 12 |
from circumstances_dropdowns import *
|
| 13 |
from physical_select_animal import show_physical, find_bounding_box
|
| 14 |
+
from physical_checkbox import on_select_body_part
|
| 15 |
+
from behavior_checkbox import show_behavior, on_select_behavior
|
| 16 |
+
from style import *
|
| 17 |
+
from theme import theme, css
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
+
with gr.Blocks(theme=theme, css=css) as demo:
|
| 20 |
# with gr.Tab("Tab 1"):
|
| 21 |
+
show_modal = gr.Button("Add an Animal")
|
| 22 |
+
df = gr.Dataframe(headers=get_headers(),
|
| 23 |
+
visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
with Modal(visible=False) as modal:
|
| 25 |
# ---------------------------------------------------------
|
| 26 |
# Intro Text
|
|
|
|
| 44 |
identified_location= gr.Textbox(visible=False, interactive=False,
|
| 45 |
label="Identified GPS Location")
|
| 46 |
with gr.Row():
|
| 47 |
+
#to submit it
|
| 48 |
+
submit_location = gr.Button("Get GPS Coordinates",
|
| 49 |
+
visible=True, interactive=True, scale=3)
|
| 50 |
+
submit_location.click(get_location, inputs=[location], outputs=[identified_location])
|
| 51 |
#to clear it
|
| 52 |
+
clear_location = gr.ClearButton(components=[location, identified_location],
|
| 53 |
+
visible=True, interactive=True, scale=1
|
| 54 |
)
|
| 55 |
clear_location.click()
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
# ---------------------------------------------------------
|
| 58 |
# ---------------------------------------------------------
|
|
|
|
| 81 |
|
| 82 |
# ---------------------------------------------------------
|
| 83 |
# ---------------------------------------------------------
|
| 84 |
+
# ---------------------------------------------------------
|
| 85 |
# Dead Button Logic
|
| 86 |
partial_show_section_dead = partial(show_section_dead, True)
|
| 87 |
partial_hide_section_wounded = partial(show_section_wounded, False)
|
|
|
|
| 129 |
button_natural_cause_dead.click(dropdown_natural_cause, outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
| 130 |
|
| 131 |
dropdown_dead.select(on_select, None, [dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead])
|
| 132 |
+
dropdown_level2_dead.select(on_select_dropdown_level2)
|
| 133 |
+
openfield_level2_dead.select(on_select_openfield_level2)
|
| 134 |
+
dropdown_extra_level2_dead.select(on_select_dropdown_extra_level2)
|
| 135 |
# ---------------------------------------------------------
|
| 136 |
# Radio Cause Wounded
|
| 137 |
radio_cause_wounded.change(fn=show_causes,
|
|
|
|
| 156 |
radio_behavior_wounded.change(fn=show_behavior,
|
| 157 |
inputs=[radio_behavior_wounded, gr.Text("wounded", visible=False)],
|
| 158 |
outputs=[behavior_checkbox, behavior_text])
|
| 159 |
+
behavior_checkbox.select(on_select_behavior,
|
| 160 |
+
inputs=[behavior_checkbox])
|
| 161 |
# ---------------------------------------------------------
|
| 162 |
# Radio Physical Wounded
|
| 163 |
radio_physical_wounded.change(fn=show_physical,
|
|
|
|
| 167 |
# Checkbox Physical Wounded
|
| 168 |
physical_boxes_wounded.select(find_bounding_box,
|
| 169 |
inputs=[physical_boxes_wounded, gr.Textbox(value="wounded", visible=False)],
|
| 170 |
+
outputs=[checkbox_beak, text_beak,
|
| 171 |
+
checkbox_body, text_body,
|
| 172 |
+
checkbox_feathers, text_feathers,
|
| 173 |
+
checkbox_head, text_head,
|
| 174 |
+
checkbox_legs, text_legs
|
| 175 |
])
|
| 176 |
+
checkbox_beak.select(on_select_body_part, inputs=[checkbox_beak, gr.Text("beak", visible=False)])
|
| 177 |
+
checkbox_body.select(on_select_body_part, inputs=[checkbox_body, gr.Text("body", visible=False)])
|
| 178 |
+
checkbox_feathers.select(on_select_body_part, inputs=[checkbox_feathers, gr.Text("feathers", visible=False)])
|
| 179 |
+
checkbox_head.select(on_select_body_part, inputs=[checkbox_head, gr.Text("head", visible=False)])
|
| 180 |
+
checkbox_legs.select(on_select_body_part, inputs=[checkbox_legs, gr.Text("legs", visible=False)])
|
| 181 |
|
| 182 |
+
# ---------------------------------------------------------
|
| 183 |
+
# Add One Individual's Data to the Dataframe
|
| 184 |
+
with gr.Row():
|
| 185 |
+
button_df = gr.Button("Submit Animal Report", scale = 3)
|
| 186 |
+
button_clear = gr.ClearButton(scale = 1,
|
| 187 |
+
components=[
|
| 188 |
+
location, identified_location,
|
| 189 |
+
button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
|
| 190 |
+
dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead,
|
| 191 |
+
radio_cause_wounded, radio_behavior_wounded, radio_physical_wounded,
|
| 192 |
+
button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
|
| 193 |
+
dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
|
| 194 |
+
behavior_checkbox, behavior_text,
|
| 195 |
+
physical_boxes_wounded,
|
| 196 |
+
checkbox_beak, text_beak, checkbox_body, text_body, checkbox_feathers, text_feathers, checkbox_head, text_head, checkbox_legs, text_legs
|
| 197 |
+
])
|
| 198 |
+
button_clear.click()
|
| 199 |
+
button_df.click(save_individual_to_df,
|
| 200 |
+
inputs=[df],
|
| 201 |
+
outputs=[df])
|
| 202 |
+
button_df.click(lambda: Modal(visible=False), None, modal)
|
| 203 |
+
show_modal.click(lambda: Modal(visible=True), None, modal)
|
| 204 |
+
show_modal.click(create_json)
|
| 205 |
|
| 206 |
|
| 207 |
|
app/physical_checkbox.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
from utils_config import get_custom_config_dropdowns
|
| 3 |
from utils_checkbox import create_checkbox
|
|
|
|
| 4 |
#---------------------------------------------------------
|
| 5 |
def get_body_parts():
|
| 6 |
dropdown_config = get_custom_config_dropdowns("config_checkbox_physical.json")
|
|
@@ -68,4 +69,7 @@ def process_body_parts(section, matched_box):
|
|
| 68 |
checkbox_legs, text_legs = create_checkbox_legs(section, label_checkbox, visibles[4])
|
| 69 |
return checkbox_beak, text_beak, checkbox_body, text_body, checkbox_feathers, text_feathers, checkbox_head, text_head, checkbox_legs, text_legs
|
| 70 |
|
| 71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from utils_config import get_custom_config_dropdowns
|
| 3 |
from utils_checkbox import create_checkbox
|
| 4 |
+
from utils_json import add_data_to_individual
|
| 5 |
#---------------------------------------------------------
|
| 6 |
def get_body_parts():
|
| 7 |
dropdown_config = get_custom_config_dropdowns("config_checkbox_physical.json")
|
|
|
|
| 69 |
checkbox_legs, text_legs = create_checkbox_legs(section, label_checkbox, visibles[4])
|
| 70 |
return checkbox_beak, text_beak, checkbox_body, text_body, checkbox_feathers, text_feathers, checkbox_head, text_head, checkbox_legs, text_legs
|
| 71 |
|
| 72 |
+
#---------------------------------------------------------
|
| 73 |
+
|
| 74 |
+
def on_select_body_part(body_part_checkbox, body_part):
|
| 75 |
+
add_data_to_individual("physical_changes_" + body_part, body_part_checkbox)
|
app/utils_df.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import pandas as pd
|
| 3 |
+
from dotenv import load_dotenv
|
| 4 |
+
from utils_config import load_config
|
| 5 |
+
from utils_json import get_json_one_individual
|
| 6 |
+
import os
|
| 7 |
+
load_dotenv()
|
| 8 |
+
PATH = os.getcwd() + "/"
|
| 9 |
+
PATH_ASSETS = os.getenv('PATH_ASSETS')
|
| 10 |
+
PATH_CONFIG = PATH + PATH_ASSETS + "config/"
|
| 11 |
+
|
| 12 |
+
def get_headers():
|
| 13 |
+
headers_config = load_config(PATH_CONFIG + "config_df.json")
|
| 14 |
+
headers = headers_config["headers"]
|
| 15 |
+
return headers
|
| 16 |
+
|
| 17 |
+
def match_data_to_headers(headers, one_individual):
|
| 18 |
+
new_row = {}
|
| 19 |
+
for key in headers:
|
| 20 |
+
if key in one_individual:
|
| 21 |
+
if type(one_individual[key])==list:
|
| 22 |
+
new_row[key] = ' , '.join(one_individual[key])
|
| 23 |
+
else:
|
| 24 |
+
new_row[key] = one_individual[key]
|
| 25 |
+
else:
|
| 26 |
+
new_row[key] = "NA"
|
| 27 |
+
return list(new_row.values())
|
| 28 |
+
|
| 29 |
+
def save_individual_to_df(df):
|
| 30 |
+
headers = get_headers()
|
| 31 |
+
one_individual = get_json_one_individual()
|
| 32 |
+
new_row = match_data_to_headers(headers, one_individual)
|
| 33 |
+
new_row_df = pd.DataFrame([new_row], columns=headers)
|
| 34 |
+
df_new = pd.concat([df, new_row_df], ignore_index=True)
|
| 35 |
+
df_gr = gr.DataFrame(visible=True,
|
| 36 |
+
value=df_new,
|
| 37 |
+
headers=headers)
|
| 38 |
+
return df_gr
|
app/utils_json.py
CHANGED
|
@@ -2,7 +2,7 @@ import json
|
|
| 2 |
|
| 3 |
def create_json(one_individual={}):
|
| 4 |
# Serializing json
|
| 5 |
-
one_individual = json.dumps(one_individual
|
| 6 |
# Writing to sample.json
|
| 7 |
with open("data/one_individual.json", "w") as outfile:
|
| 8 |
outfile.write(one_individual)
|
|
@@ -14,3 +14,8 @@ def add_data_to_individual(key, value):
|
|
| 14 |
one_individual[key] = value
|
| 15 |
create_json(one_individual)
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
def create_json(one_individual={}):
|
| 4 |
# Serializing json
|
| 5 |
+
one_individual = json.dumps(one_individual)
|
| 6 |
# Writing to sample.json
|
| 7 |
with open("data/one_individual.json", "w") as outfile:
|
| 8 |
outfile.write(one_individual)
|
|
|
|
| 14 |
one_individual[key] = value
|
| 15 |
create_json(one_individual)
|
| 16 |
|
| 17 |
+
def get_json_one_individual():
|
| 18 |
+
with open("data/one_individual.json", 'r') as openfile:
|
| 19 |
+
one_individual = json.load(openfile)
|
| 20 |
+
return one_individual
|
| 21 |
+
|
app/wounded.py
CHANGED
|
@@ -9,8 +9,8 @@ from utils_json import add_data_to_individual
|
|
| 9 |
def show_section_wounded(visible):
|
| 10 |
if visible==True:
|
| 11 |
add_data_to_individual("wounded", "True")
|
| 12 |
-
|
| 13 |
-
|
| 14 |
with gr.Column(visible=visible, elem_id="wounded") as wounded_section:
|
| 15 |
gr.Markdown("# Wounded Animal")
|
| 16 |
|
|
|
|
| 9 |
def show_section_wounded(visible):
|
| 10 |
if visible==True:
|
| 11 |
add_data_to_individual("wounded", "True")
|
| 12 |
+
add_data_to_individual("dead", "False")
|
| 13 |
+
|
| 14 |
with gr.Column(visible=visible, elem_id="wounded") as wounded_section:
|
| 15 |
gr.Markdown("# Wounded Animal")
|
| 16 |
|