Datos Geoespaciales en Python

In [2]:
# Importamos paquetes o librerías necesarias para desarrollar este proyecto

import datetime
import pandas as pd
import geopandas as gpd
import json
from bokeh.io import curdoc, output_notebook
from bokeh.models import Slider, HoverTool
from IPython.display import YouTubeVideo
In [3]:
# Muestra la fecha de última ejecución del notebook
print("Actualizado al: " + str(datetime.datetime.now().strftime("%Y-%b-%d %H:%M")))
Actualizado al: 2019-Nov-25 22:37

Contenido

  1. Introducción
  2. Datos Geoespaciales
  3. Ejercicio 1. PHLI México
  4. Coméntanos















Introducción

Para todo científico de datos es muy atractivo poder analizar información geográfica y realizar visualizaciones interactivas con ella. En el presente proyecto haremos uso de la plataforma mexicana de datos abiertos para obtener archivos de datos geográficos y procesarlos para analizarlos.
Como todo proyecto de Pakin Ciencia de Datos, el presente proyecto es incremental por lo que periódicamente se añaden más ejercicios y desarrollos.
El código Python utilizado para generar todos los análisis y visualizaciones, está disponible con el botón en la parte superior ó puedes esconder el código si tu finalidad es consultar la información.

Regresar al inicio


Datos Geoespaciales

Los archivos del tipo shapefile (desarrollados por ESRI: Enviromental Systems Research Institute) son actualmente los más utilizados para contener datos de vectores geo-espaciales. Los archivos *.shp vienen acompañados de otros varios archivos cada uno con una función específica y un tipo de información como (elementos geométricos, proyección, metadata, atributos, etc.), estos archivos suelen ser:

  • .shp: contiene la geometría de las variables (características)
  • .shx: contiene la indexación de la geometría
  • .dbf: contiene los atributos de las variables
  • .prj: contiene información sobre el sistema de coordenadas y la información de proyección
  • .sbn | .sbx: contienen indexación espacial de las variables
  • .shp.xml: contiene metadata geo-espacial
  • .lyr: contiene la ruta a un conjunto de datos de origen y otras propiedades de capa, incluida la simbología.

Es importante que estos archivos tengan el mismo nombre (salvo la extención) y se encuentren en el mismo directorio para poder trabajar con el conjunto en Python y otros lenguajes de programación.

Regresar al inicio


Personas Hablantes de Lenguas Indígenas en México

Importación y Exploración de Datos

La mejor manera de comprender nuestros archivos y datos es realizando una exploración de los mismos.
En este primer ejercicio haremos uso de la plataforma datos.gob.mx para obtener los archivos correspondientes a "Hablantes de lengua indígena 2000". Lamentablemente en la plataforma no existe esta información para un año más actual. Puedes descargar aquí el conjunto de archivos: "Hablantes de lengua indígena 2000".
Haremos uso de la librería GeoPandas que nos permitirá trabajar con datos geo-espaciales de una manera más sencialla.

In [4]:
# Declaramos una variable con la ruta al archivo .shp
path = '/home/pakin/Downloads/PHLIM/PHLITL_2000.shp'

# Importamos los datos
data = gpd.read_file(path)

Exploremos el tipo de objeto que obtenemos y el número y nombres de las variables incluidas en el conjunto de datos:

In [5]:
data.info()
<class 'geopandas.geodataframe.GeoDataFrame'>
RangeIndex: 2480 entries, 0 to 2479
Data columns (total 20 columns):
AREA          2480 non-null float64
PERIMETER     2480 non-null float64
DPHLIL_       2480 non-null int64
DPHLIL_ID     2480 non-null int64
EDO_NUM       2480 non-null int64
EDO_LEY       2480 non-null object
MPO_NUM       2480 non-null float64
MPO_LEY       2480 non-null object
PHLI_TOT      2480 non-null int64
PHLI_TML1     2480 non-null int64
PHLI_TML2     2480 non-null int64
PHLI_TML3     2480 non-null int64
PHLI_TML4     2480 non-null int64
ICON_TML1     2480 non-null float64
ICON_TML2     2480 non-null float64
ICON_TML3     2480 non-null float64
ICON_TML4     2480 non-null float64
DPHLIL_NUM    2480 non-null int64
DPHLIL_LEY    2480 non-null object
geometry      2480 non-null object
dtypes: float64(7), int64(9), object(4)
memory usage: 387.6+ KB

Tenemos un objeto tipo GeoDataFrame que hereda muchas de las propiedades y métodos de un pandas DataFrame. El conjunto de datos contiene 20 variables con 2480 observaciones (renglones).

Observemos las primeras filas del GeoDataFrame:

In [6]:
data.head()
Out[6]:
AREA PERIMETER DPHLIL_ DPHLIL_ID EDO_NUM EDO_LEY MPO_NUM MPO_LEY PHLI_TOT PHLI_TML1 PHLI_TML2 PHLI_TML3 PHLI_TML4 ICON_TML1 ICON_TML2 ICON_TML3 ICON_TML4 DPHLIL_NUM DPHLIL_LEY geometry
0 1.311912e+10 7.801129e+05 2 1473 2 Baja California 2002.0 Mexicali 5480 862 234 439 3945 0.26 0.39 0.92 3.79 8 De 15,000 y mas POLYGON ((788992.7599999954 3707437.079667801,...
1 9.033662e+09 5.335922e+05 3 1617 26 Sonora 26055.0 San Luis Río Colorado 874 106 19 71 678 0.20 0.20 0.94 4.09 8 De 15,000 y mas POLYGON ((788992.7599999954 3707437.079667801,...
2 5.346384e+10 1.962698e+06 4 1476 2 Baja California 2001.0 Ensenada 16449 6028 2949 4322 3150 0.60 1.64 3.03 1.01 7 De 5,000 a 14,999 y de 15,000 y mas POLYGON ((783083.2999999949 3526355.799667791,...
3 6.200604e+09 7.831287e+05 5 1618 26 Sonora 26048.0 Puerto Peñasco 397 3 0 0 394 0.01 0.00 0.00 5.23 8 De 15,000 y mas POLYGON ((901967.8399999959 3655406.799667796,...
4 3.723828e+09 3.953913e+05 6 1598 26 Sonora 26070.0 General Plutarco Elías Calle 144 17 0 127 0 0.19 0.00 10.18 0.00 6 De 5,000 a 14,999 POLYGON ((1014518.909999996 3604588.009667793,...

Preparación de Datos

Para este ejecicio nos interesan las variables EDO_LEY que contiene el nombre del estado de la República, MPO_LEY que tiene el nombre del municipio, DPHLIL_LEY que contiene el número de personas hablantes de lenguas indígenas en dicho municipio y geometry que tiene los datos geométricos.

In [7]:
#Importamos de nuevo el archivo .shp pero únicamente con los campos de interés
data_f = gpd.read_file(path)[['EDO_LEY','MPO_LEY','DPHLIL_LEY', 'geometry']]

Para poder trabajar fácilmente con la variable DPHLIL_LEY definiremos una nueva variable DPHLIL_LEY_N definiendo un valor numérico en la escala del 1 al 8 según la siguientes categorías:

In [8]:
data_f['DPHLIL_LEY_N'] = data_f['DPHLIL_LEY'].map({
               'Sin poblacion hablante de lengua indigena':0,
               'Menor de 2,500':1,
               'De 2,500 a 4,999':2,
               'Menor de 2,500 y de 2,500 a 4,999':3,
               'De 2,500 a 4,999 y de 5,000 a 14,999':4,
               'Menor de 2,500 y de 5,000 a 14,999':5,
               'De 5,000 a 14,999':6,
               'De 5,000 a 14,999 y de 15,000 y mas':7,
               'De 15,000 y mas':8})

Exploremos el resultado:

In [9]:
data_f.head()
Out[9]:
EDO_LEY MPO_LEY DPHLIL_LEY geometry DPHLIL_LEY_N
0 Baja California Mexicali De 15,000 y mas POLYGON ((788992.7599999954 3707437.079667801,... 8
1 Sonora San Luis Río Colorado De 15,000 y mas POLYGON ((788992.7599999954 3707437.079667801,... 8
2 Baja California Ensenada De 5,000 a 14,999 y de 15,000 y mas POLYGON ((783083.2999999949 3526355.799667791,... 7
3 Sonora Puerto Peñasco De 15,000 y mas POLYGON ((901967.8399999959 3655406.799667796,... 8
4 Sonora General Plutarco Elías Calle De 5,000 a 14,999 POLYGON ((1014518.909999996 3604588.009667793,... 6

Con el fin de utilizar la grandiosa librería Bokeh, transformaremos el objeto GeoDataFrame a un objeto del tipo json:

In [10]:
m_data = json.loads(data_f.to_json())
json_data = json.dumps(m_data)

Visualización Interactiva

Ahora creamos la visualización interactiva:

In [11]:
from bokeh.io import output_notebook, show, output_file
from bokeh.plotting import figure
from bokeh.models import GeoJSONDataSource, LinearColorMapper, ColorBar
from bokeh.palettes import brewer, all_palettes, small_palettes
In [12]:
# Creamos un objeto GeoJSON que contiene las variables que graficaremos
geosource = GeoJSONDataSource(geojson = json_data)
In [13]:
# Definimos una paleta de colores
palette =  all_palettes['Viridis'][9]
#Ordenamos la paleta de colores de forma inversa
palette = palette[::-1]
#Instantiate LinearColorMapper that linearly maps numbers in a range, into a sequence of colors.
color_mapper = LinearColorMapper(palette = palette, low = 0, high = 8)
In [14]:
#Add hover tool
TOOLTIPS = [('ESTADO','@EDO_LEY'),('MUNICIPIO','@MPO_LEY'),('CANTIDAD', '@DPHLIL_LEY')]
In [15]:
#Create figure object.

p = figure(title = 'Personas Hablantes de Lenguas Indígenas en Cada Municipio Mexicano',
           plot_height = 300,
           plot_width = 500,
           toolbar_location = 'right',
           tooltips = TOOLTIPS,
           sizing_mode = 'scale_width'
          )


p.xaxis.visible = None
p.yaxis.visible = None
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
p.title.align = 'center'
p.title.text_font_size = "14px"
In [16]:
#
p.patches('xs','ys', source = geosource, fill_color = {'field':'DPHLIL_LEY_N','transform':color_mapper},
          line_color = 'black', line_width = 0.25, fill_alpha = 1)
Out[16]:
GlyphRenderer(
id = '1044', …)
In [17]:
#Configuramos para presentar la imagen inline
output_notebook()
Loading BokehJS ...
In [18]:
# Muestra la visualización
#show(p)

Debido a que la visualización interactiva es demasiado pesada para insertar en una página, aquí mostramos una imagen de ella:

Información Geo-espacial Lenguas Indígenas México

Con el fin de tener una visualización más limpia, no hemos añadido una barra de escala de colores, pero colocando el ratón sobre la visualización se obtiene toda la información importante.
Lamentablemente en la plataforma de datos abiertos no se encuentra algún diccionario o metadata que pueda explicar de mejor manera las escalas (número de personas) y las lenguas así como datos más actuales; sin embargo los datos son perfectos para desarrollar el ejercicio y trabajar con datos geo-espaciales.
En breve publicaremos un siguiente ejercicio.

Regresar al inicio


Síguenos en Facebook


Pakin en Facebook

Esperamos con gusto tus comentarios y sugerencias para incrementar y mejorar este proyecto: