Razkaroth commited on
Commit
77ed535
·
1 Parent(s): a11e95a

Explorador listo

Browse files
__pycache__/diagnostics.cpython-311.pyc ADDED
Binary file (1.88 kB). View file
 
app.py CHANGED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import geopandas as gpd
4
+ from diagnostics import run_df_diagnostics
5
+ import plotly.express as px
6
+
7
+
8
+ st.set_page_config(
9
+ page_title="Explorador REPDA",
10
+ page_icon="🧊",
11
+ layout="wide",
12
+ )
13
+
14
+ st.title("Explorador REPDA")
15
+
16
+
17
+ def load_data():
18
+ df = pd.read_json("data.json")
19
+ df = df.drop_duplicates()
20
+
21
+ return df
22
+
23
+
24
+ df = load_data()
25
+
26
+ # run_df_diagnostics(df, "Datos iniciales")
27
+
28
+
29
+ # Filters
30
+
31
+ st.sidebar.header("Filtros")
32
+
33
+ categorical_columns = {
34
+ "Titular": "titular",
35
+ "Título": "titulo",
36
+ "Uso amparado": "uso_amparado",
37
+ "Anotaciones marginales": "anotaciones_marginales",
38
+ "Tipo de anexo": "tipo_de_anexo",
39
+ "Estado": "estado",
40
+ "Municipio": "municipio",
41
+ "Región hidrológica": "region_hidrologica",
42
+ "Cuenca": "cuenca",
43
+ "Acuífero": "acuifero",
44
+ "Acuifero homologado": "acuifero_homologado",
45
+ }
46
+
47
+ st.sidebar.write("Filtrado por region via GeoJSON")
48
+ st.sidebar.write("Instrucciones: Entra a https://geojson.io/ y dibuja un poligono")
49
+ st.sidebar.write("Despues descarga el archivo como GeoJSON y cargalo aqui")
50
+ geojson = st.sidebar.file_uploader("Cargar GeoJSON", type=["geojson"])
51
+
52
+ if geojson is not None:
53
+ gdf = gpd.read_file(geojson)
54
+ df = gpd.GeoDataFrame(df)
55
+ df["geometry"] = df.apply(lambda row: gpd.points_from_xy([row.lon], [row.lat])[0], axis=1)
56
+ df.set_geometry('geometry')
57
+ df = gpd.sjoin(df, gdf, op="within")
58
+ df = df.drop(columns=["geometry", "index_right"])
59
+ df = pd.DataFrame(df)
60
+
61
+
62
+ columns = st.sidebar.multiselect(
63
+ "Selecciona columnas para filtrar por valor",
64
+ categorical_columns.keys(),
65
+ )
66
+
67
+ if columns:
68
+ for column in columns:
69
+ key = categorical_columns[column]
70
+ column_filters = st.sidebar.multiselect(
71
+ f"Selecciona valores para: {column}",
72
+ df[key].unique().tolist(),
73
+ )
74
+ if column_filters:
75
+ df = df[df[key].isin(column_filters)]
76
+
77
+ numeric_columns = {
78
+ "Volumen total de aguas nacionales": "volumen_total_de_aguas_nacionales",
79
+ "Volumen total de aguas superficiales": "volumen_total_de_aguas_superficiales",
80
+ "Volumen total de aguas subterráneas": "volumen_total_de_aguas_subterraneas",
81
+ "Volumen total de descargas": "volumen_total_de_descargas",
82
+ "Número de descargas en el título": "anexos_descargas",
83
+ "Número de tomas subtarráneas en el título": "anexos_subterraneos",
84
+ "Número de tomas superficiales en el título": "anexos_superficiales",
85
+ "Número de tomas en zonas federales en el título": "anexos_zonas_federales",
86
+ "Volumen individual": "volumen",
87
+ "Superficie": "superficie",
88
+ "Volumen de descarga diario": "volumen_de_descarga_diario",
89
+ "Volumen de descarga anual": "volumen_de_descarga_anual",
90
+ }
91
+
92
+ # Check if there are not None values in columns
93
+ numeric_columns_alive = {}
94
+ other_category_columns = (
95
+ set(df.columns.tolist())
96
+ - set(numeric_columns.values())
97
+ - set(categorical_columns.values())
98
+ )
99
+
100
+ other_catergory_columns_alive = {}
101
+ for key in other_category_columns:
102
+ if df[key].notnull().any():
103
+ other_catergory_columns_alive[key.capitalize().replace("_", " ")] = key
104
+
105
+ if other_catergory_columns_alive.keys() != []:
106
+ other_category_columns = st.sidebar.multiselect(
107
+ "Selecciona columnas para filtrar",
108
+ other_catergory_columns_alive.keys(),
109
+ )
110
+ if other_category_columns:
111
+ for key in other_category_columns:
112
+ column_name = other_catergory_columns_alive[key]
113
+ column_filters = st.sidebar.multiselect(
114
+ f"Selecciona valores para: {key}",
115
+ df[column_name].unique().tolist(),
116
+ )
117
+ if column_filters:
118
+ df = df[df[column_name].isin(column_filters)]
119
+
120
+ for key, column_name in numeric_columns.items():
121
+ if df[column_name].notnull().any():
122
+ if df[column_name].min() != df[column_name].max():
123
+ numeric_columns_alive[key] = column_name
124
+
125
+
126
+ if numeric_columns_alive.keys() != []:
127
+ numeric_column_filters = st.sidebar.multiselect(
128
+ "Selecciona columnas para filtrar por rango",
129
+ numeric_columns_alive.keys(),
130
+ )
131
+ if numeric_column_filters:
132
+ for key in numeric_column_filters:
133
+ column_name = numeric_columns_alive[key]
134
+ st.sidebar.write(f"Escoge un rango para: {key}")
135
+ min_value = st.sidebar.slider(
136
+ f"Valor mínimo para: {key}",
137
+ df[column_name].min(),
138
+ df[column_name].max(),
139
+ df[column_name].min(),
140
+ )
141
+ max_value = st.sidebar.slider(
142
+ f"Valor máximo para: {key}",
143
+ df[column_name].min(),
144
+ df[column_name].max(),
145
+ df[column_name].max(),
146
+ )
147
+ # drop rows that are NONE for that column
148
+
149
+ df = df[(df[column_name] >= min_value) & (df[column_name] <= max_value)]
150
+
151
+
152
+ # run_df_diagnostics(df, "Datos filtrados")
153
+
154
+
155
+ st.header("Mapa")
156
+
157
+
158
+ mapbox = px.scatter_mapbox(
159
+ df,
160
+ lat="lat",
161
+ lon="lon",
162
+ color="tipo_de_anexo",
163
+ hover_name="titular",
164
+ hover_data=[
165
+ "titulo",
166
+ "estado",
167
+ "municipio",
168
+ "region_hidrologica",
169
+ "cuenca",
170
+ "acuifero",
171
+ ],
172
+ color_discrete_sequence=px.colors.qualitative.Vivid,
173
+ zoom=4,
174
+ height=900,
175
+ width=1000,
176
+ center={"lat": 23.634501, "lon": -102.552784},
177
+ mapbox_style="carto-positron",
178
+ )
179
+ mapbox.update_traces(marker={"size": 8})
180
+
181
+ st.plotly_chart(mapbox)
182
+
183
+
184
+ st.header("Datos")
185
+
186
+ st.dataframe(df)
187
+
188
+ st.download_button(
189
+ label="Descargar datos",
190
+ data=df.to_csv().encode("utf-8"),
191
+ file_name="data.csv",
192
+ mime="text/csv",
193
+ )
diagnostics.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+
4
+
5
+ def run_df_diagnostics(df: pd.DataFrame, name: str = 'df'):
6
+ show = st.checkbox(f'Mostrar diagnóstico de {name}')
7
+ if show:
8
+ expander = st.expander(f'Diagnóstico de {name}')
9
+ expander.write(f'Filas: {df.shape[0]}')
10
+ expander.write(f'Columnas: {df.shape[1]}')
11
+ expander.write('Columnas')
12
+ expander.write(df.columns.tolist())
13
+ expander.write('Tipos de datos')
14
+ expander.write(df.dtypes)
15
+ expander.write('Descripción')
16
+ expander.write(df.describe())
17
+ expander.write('Head (5)')
18
+ expander.write(df.head())
19
+ expander.write('Tail (5)')
20
+ expander.write(df.tail())
21
+
requirements.txt CHANGED
@@ -1,5 +1,6 @@
1
  altair==5.1.2
2
  attrs==23.1.0
 
3
  blinker==1.7.0
4
  cachetools==5.3.2
5
  certifi==2023.11.17
@@ -8,6 +9,7 @@ click==8.1.7
8
  click-plugins==1.1.1
9
  cligj==0.7.2
10
  fiona==1.9.5
 
11
  geopandas==0.14.1
12
  gitdb==4.0.11
13
  GitPython==3.1.40
@@ -18,14 +20,22 @@ jsonschema==4.20.0
18
  jsonschema-specifications==2023.11.1
19
  markdown-it-py==3.0.0
20
  MarkupSafe==2.1.3
 
21
  mdurl==0.1.2
 
22
  numpy==1.26.2
23
  packaging==23.2
24
  pandas==2.1.3
 
 
25
  Pillow==10.1.0
 
 
26
  protobuf==4.25.1
27
  pyarrow==14.0.1
 
28
  pydeck==0.8.1b0
 
29
  Pygments==2.17.1
30
  pyproj==3.6.1
31
  python-dateutil==2.8.2
@@ -42,6 +52,7 @@ tenacity==8.2.3
42
  toml==0.10.2
43
  toolz==0.12.0
44
  tornado==6.3.3
 
45
  typing_extensions==4.8.0
46
  tzdata==2023.3
47
  tzlocal==5.2
 
1
  altair==5.1.2
2
  attrs==23.1.0
3
+ black==23.11.0
4
  blinker==1.7.0
5
  cachetools==5.3.2
6
  certifi==2023.11.17
 
9
  click-plugins==1.1.1
10
  cligj==0.7.2
11
  fiona==1.9.5
12
+ flake8==6.1.0
13
  geopandas==0.14.1
14
  gitdb==4.0.11
15
  GitPython==3.1.40
 
20
  jsonschema-specifications==2023.11.1
21
  markdown-it-py==3.0.0
22
  MarkupSafe==2.1.3
23
+ mccabe==0.7.0
24
  mdurl==0.1.2
25
+ mypy-extensions==1.0.0
26
  numpy==1.26.2
27
  packaging==23.2
28
  pandas==2.1.3
29
+ pandas-stubs==2.1.1.230928
30
+ pathspec==0.11.2
31
  Pillow==10.1.0
32
+ platformdirs==4.0.0
33
+ plotly==5.18.0
34
  protobuf==4.25.1
35
  pyarrow==14.0.1
36
+ pycodestyle==2.11.1
37
  pydeck==0.8.1b0
38
+ pyflakes==3.1.0
39
  Pygments==2.17.1
40
  pyproj==3.6.1
41
  python-dateutil==2.8.2
 
52
  toml==0.10.2
53
  toolz==0.12.0
54
  tornado==6.3.3
55
+ types-pytz==2023.3.1.1
56
  typing_extensions==4.8.0
57
  tzdata==2023.3
58
  tzlocal==5.2