Hola De Intercambio De La Pila,
Para la vida de mí no puedo averiguar qué estoy haciendo mal en este punto. Soy un programador principiante así que estoy orgulloso de llegar aquí; sin embargo, si hay otras soluciones que son más efectivos por favor, siéntase libre de sugerir.
Archivos De Datos:
- gdf_final_serial
- ↑ Esta es una versión abreviada como los datos reales es ~680K Filas
- geo_school
- ^Json ser utilizado
Lo que necesita el Guión aplicación para hacer:
- Trabajo como un Multi-Filtrables Mapa de los SIG en lo que respecta a los campos de la lista (Condado, Distrito, Nombre, Edad, RE, Cuartiles, Vivienda Insegura)
- En base a los filtros elegido, la actualización de los px.choropleth_mapbox con el recuento exacto de los 'puntos'.
Vamos a saltar en el código. También estoy ejecutando esto en Google Colab Notebook.
filename_1 = root_path+"schoolDistrictBoundaries_Fixed.json"
file = open(filename_1)
schoolDistricts = gpd.read_file(file)
^^ se llevaron a cabo en una celda global
import dash
import dash.dependencies
import plotly.express as px
import pandas as pd
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import numpy as np
px.set_mapbox_access_token(mapbox_access_token)
### Creating gdf_final_serial
geo_df = gpd.GeoDataFrame.from_features(geo_school["features"]).merge(joined, on="OBJECTID").set_index("OBJECTID") #GeoJson Join to Joined Dataframe
cleaned_geo_df = geo_df[["geometry_x", "CountyName_x", "RE", "QUARTILES", "HOUSING_INSECURE", "County", "Age", "DistrictName_x"]] #Picks the right columns
geo_df_final = cleaned_geo_df.rename(columns={"CountyName_x": "CountyName", "geometry_x": "geometry", 'DistrictName_x': 'DistrictName'}) #Changing Column Names
geo_df_final.to_pickle(root_path+"geo_df_final") #Write to drive as a pickle to serialize
df_final_serial = pd.read_pickle(root_path+"geo_df_final") #Read as DataFrame
gdf_final_serial = gpd.GeoDataFrame(data = df_final_serial, geometry= "geometry", crs = "epsg:4326") #Turn into GeoPandas DataFrame and set the geometry and crs
re_indicators = gdf_final_serial.RE.unique()
county_indicators = gdf_final_serial.CountyName.unique()
age_indicators = gdf_final_serial.Age.unique()
district_indicators = gdf_final_serial.DistrictName.unique()
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = JupyterDash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
[
html.Div(
children=[
html.Label("County"),
dcc.Checklist(
id="county",
options=[{"label": i, "value": i} for i in county_indicators],
value=[]
),
html.Label("District Name"),
dcc.Dropdown(
id="dname",
options=[],
value=[],
multi=True,
),
html.Label("Age"),
dcc.Dropdown(id="age",
options=[],
value=[],
multi = True),
html.Label("RE"),
dcc.Dropdown(id="re",
options=[],
value=[],
multi = True),
html.Label("Quartiles"),
dcc.Dropdown(id="quartiles",
options=[],
value=[],
multi=True),
html.Label("Housing"),
dcc.Dropdown(id="housing",
options=[],
value=[],
multi=True),
dcc.Graph(id="my_map", figure={})])
]
)
@app.callback(
dash.dependencies.Output("dname", "options"),
dash.dependencies.Input("county", "value")
)
def choose_county(county_pick):
if len(county_pick) > 0:
dff=gdf_final_serial[gdf_final_serial.CountyName.isin(county_pick)]
else:
raise dash.exceptions.PreventUpdate
return [{"label": i, "value": i} for i in (dff.DistrictName.unique())]
@app.callback(
dash.dependencies.Output("dname", "value"),
dash.dependencies.Input("dname", "options"),
)
def set_city_value(available_options_dname):
return [x["value"] for x in available_options_dname]
@app.callback(
dash.dependencies.Output("age", "options"),
dash.dependencies.Input("dname", "value")
)
def dname_age_picker(choose_dname):
print(choose_dname)
if len(choose_dname) > 0:
dff = gdf_final_serial[gdf_final_serial.DistrictName.isin(choose_dname)]
else:
raise dash.exceptions.PreventUpdate
return [{"label": i, "value": i} for i in (dff.Age.unique())]
@app.callback(
dash.dependencies.Output("age", "value"),
dash.dependencies.Input("age", "options"),
)
def set_age_value(available_options_age):
return [x["value"] for x in available_options_age]
@app.callback(
dash.dependencies.Output("re", "options"),
dash.dependencies.Input("age", "value")
)
def age_re_picker(choose_age):
if len(choose_age) > 0:
dff = gdf_final_serial[gdf_final_serial.Age.isin(choose_age)].dropna(axis = 0, how = 'any', subset = ["RE"])
else:
raise dash.exceptions.PreventUpdate
return [{"label": i, "value": i} for i in (dff.RE.unique())]
@app.callback(
dash.dependencies.Output("re", "value"),
dash.dependencies.Input("re", "options")
)
def set_re_value(available_options_re):
return [x["value"] for x in available_options_re]
@app.callback(
dash.dependencies.Output("quartiles", "options"),
dash.dependencies.Input("re", "value")
)
def re_quartile_picker(choose_re_value):
if len(choose_re_value) >= 0:
dff = gdf_final_serial[gdf_final_serial.RE.isin(choose_re_value)].dropna(axis = 0, how = 'any', subset = ["QUARTILES"])
else:
raise dash.exceptions.PreventUpdate
return [{"label": i, "value": i} for i in (dff.QUARTILES.unique())]
@app.callback(
dash.dependencies.Output("quartiles", "value"),
dash.dependencies.Input("quartiles", "options"),
)
def set_quart_value(available_options_quart):
return [x["value"] for x in available_options_quart]
@app.callback(
dash.dependencies.Output("housing", "options"),
dash.dependencies.Input("quartiles", "value")
)
def quart_picker(choose_quart_value):
if len(choose_quart_value) >= 0:
dff = gdf_final_serial[gdf_final_serial.QUARTILES.isin(choose_quart_value)]
else:
raise dash.exceptions.PreventUpdate
return [{"label": i, "value": i} for i in (dff.HOUSING_INSECURE.unique())]
@app.callback(
dash.dependencies.Output("housing", "value"),
dash.dependencies.Input("housing", "options"),
)
def set_housing_value(available_options_housing):
return [x["value"] for x in available_options_housing]
@app.callback(
dash.dependencies.Output("my_map", "figure"),
[dash.dependencies.Input("housing", "value"),
dash.dependencies.Input("quartiles", "value"),
dash.dependencies.Input("re", "value"),
dash.dependencies.Input("age", "value"),
dash.dependencies.Input("dname", "value"),
dash.dependencies.Input("county", "value")]
)
def update_fig(selected_housing, selected_quartiles, selected_re, selected_age, selected_dname, selected_county):
gdff_1 = gdf_final_serial[gdf_final_serial.CountyName.isin(selected_county) &
gdf_final_serial.DistrictName.isin(selected_dname) &
gdf_final_serial.Age.isin(selected_age) &
gdf_final_serial.RE.isin(selected_re) &
gdf_final_serial.QUARTILES.isin(selected_quartiles) &
gdf_final_serial.HOUSING_INSECURE.isin(selected_housing)]
count_points = gdff_1.groupby("OBJECTID").size().rename("points")
gdf_last = gdff_1.merge(count_points, on="OBJECTID", how="right", right_index = True)
gdf_last.to_pickle(root_path+"gdf_last") #Write to drive as a pickle to serialize
ddf_final_serial = pd.read_pickle(root_path+"gdf_last") #Read as DataFrame
gddf_final_serial = gpd.GeoDataFrame(data = ddf_final_serial, geometry= "geometry", crs = "epsg:4326")
gdff_2 = gddf_final_serial.head(50)
px.set_mapbox_access_token(mapbox_access_token)
fig = px.choropleth_mapbox(data_frame= gdff_2,
geojson= geo_school,
locations= 'DistrictName',
featureidkey = 'properties.DistrictName',
color="points",
center={"lat": 38.5941, "lon": -119.8815},
mapbox_style = 'dark').update_layout(mapbox_accesstoken = mapbox_access_token)
return fig
# Run app and display result inline in the notebook
if __name__ == "__main__":
app.run_server(host="127.0.0.1", port="8888",debug=True, use_reloader=False)
He sido capaz de recibir diversas condiciones donde el mapa/filtro producirá un solo condado, a veces dos condados, pero nunca todo el proceso. Tenga en cuenta que mi objetivo final es crear esto para la TOTALIDAD del conjunto de datos (tal vez usando RapidsAI de NVIDIA; sin embargo estoy teniendo problemas con la instalación, que como bien dentro de Google Colab).
Lo más interesante es que cuando ejecuto este código fuera de guión (como una muestra de datos reales) y pasar a la fig.show(), se mostrará; sin embargo, no funciona en el Tablero de la aplicación.
Sospecho que el problema es con mi json manipulación o el final de devolución de llamada como el depurador indica que mientras que las entradas están allí, my_map.la figura no es la salida de los datos. Agradezco la ayuda.