In [1]:
import os
import json

import folium
import numpy as np
import pandas as pd

from scipy.interpolate import interp1d

In [82]:
# Los coloresd de los bloque que mas viajan, sacados de wikipedia:
# https://es.wikipedia.org/wiki/Senado_de_la_Naci%C3%B3n_Argentina#Composici.C3.B3n_actual
colores = {'PJ Frente para la Victoria': '#0000ff', 
           'Unión Cívica Radical':'#ED1C24',
           'PJ La Pampa':'#318CE7', 
           'Movimiento Popular Neuquino':'#4169e1',
           'Justicialista San Luis': '#add8e6',
           'Frente Pro': '#FFD700',
           'Frente Cívico por Santiago':'#E60026',
           'Partido Socialista':'#fdbf6f', 
           'otros':'#ff7f00'}

bloques_validos = ['PJ Frente para la Victoria', 'Unión Cívica Radical', 'PJ La Pampa', 'Movimiento Popular Neuquino', 
                   'Justicialista San Luis', 'Frente Pro', 'Frente Cívico por Santiago', 'Partido Socialista']

In [18]:
# Se sacan los del 13 y 14 porque no tienen bloque
csvs = ['../' + csv for csv in os.listdir('../') if csv not in ['viajes_2013.csv', 'viajes_2014.csv'] 
        and csv.endswith('.csv')]

# Open and concat df
for cnt, csv in enumerate(csvs):    
    if cnt == 0:
        df = pd.read_csv(csv)
    else:
        df_temp = pd.read_csv(csv)
        df = pd.concat([df, df_temp], ignore_index=True)

In [19]:
def check_dato(destino, bloque, list_datos, origen='Argentina'):
    for dato in list_datos:
        if destino == dato['destino'] and bloque == dato['bloque'] and origen == dato['origen']:
            dato['count'] = dato['count'] + 1
            return True
    if not '/' in destino:
        viaje = {'destino':destino, 'bloque':bloque, 'origen':origen, 'count':1}
        list_datos.append(viaje)
    else:
        # Atajo los dos casos
        if ' / ' in destino:
            escala, destino = destino.split(' / ', maxsplit=1)
            escala = ' '.join(escala.split())
            destino = ' '.join(destino.split())
        elif '/' in destino:
            escala, destino = destino.split('/', maxsplit=1)
            escala = ' '.join(escala.split())
            destino = ' '.join(destino.split())
        check_dato(destino, bloque, list_datos, escala)
    return True

datos = []
for i in df.itertuples():
    check_dato(i.Destino, i.Bloque, datos)
    
count_viajes_x_destino_bloque = pd.DataFrame(datos)

In [20]:
count_viajes_x_destino_bloque.destino.unique()


Out[20]:
array(['Reino Unido de Gran Bretaña', 'Irlanda del Norte', 'España',
       'Ecuador', 'Chile', 'Estados Unidos', 'Italia', 'Panamá', 'Bélgica',
       'República de Azerbaiyán', 'Alemania', 'México', 'Bangladesh',
       'Portugal', 'Irlanda', 'Suiza', 'Cuba', 'Uruguay', 'Costa Rica',
       'Colombia', 'Emiratos Árabes Unidos', 'Grecia', 'Bolivia',
       'Corea del Sur', 'Armenia', 'Puerto Rico', 'Letonia', 'Brasil',
       'Sudáfrica', 'Francia', 'Rusia', 'Paraguay', 'Guayana',
       'República Checa', 'Aruba', 'Uganda', 'Turquía', 'Países Bajos',
       'Perú', 'República Dominicana', 'Israel', 'Canadá', 'Venezuela',
       'Suecia'], dtype=object)

In [21]:
df_counts = df.groupby('Destino')['Destino'].count()

countries_destino = set([country for country in count_viajes_x_destino_bloque.destino])
countries_origen = set([country for country in count_viajes_x_destino_bloque.origen])
countries = countries_destino.union(countries_origen)

# Elimino algos repetidos (con un espaciol al principo)
list_countries = list(countries)

In [30]:
# Lat lon del centro de cada pais
with open('centro_paises.geojson', 'r') as file:
    data = json.load(file)

In [31]:
countries = dict()
for feature in data['features']:
    nombre = feature['properties']['nombre']
    if nombre in list_countries:
        countries[nombre] = {'latlon': [feature['geometry']['coordinates'][1],
                                        feature['geometry']['coordinates'][0]]}
        
countries


Out[31]:
{'Alemania': {'latlon': [51.0871017663336, 10.370787457775123]},
 'Argentina': {'latlon': [-35.18209766247696, -65.1548248323]},
 'Armenia': {'latlon': [40.28859678761182, 44.9317308780777]},
 'Aruba': {'latlon': [12.51, -69.96833800000002]},
 'Bangladesh': {'latlon': [23.88242325782727, 90.22663495543901]},
 'Bolivia': {'latlon': [-16.706876766549385, -64.68475359110516]},
 'Brasil': {'latlon': [-16.452174485463956, -47.50483868565664]},
 'Bélgica': {'latlon': [50.83668469454318, 4.370396733222833]},
 'Canadá': {'latlon': [59.65683609990623, -117.09059449134253]},
 'Chile': {'latlon': [-35.44787283276486, -71.24781565426889]},
 'Colombia': {'latlon': [3.911188855381511, -73.07834068147713]},
 'Corea del Sur': {'latlon': [36.43732885374379, 127.88014001934664]},
 'Costa Rica': {'latlon': [9.974655552412003, -84.19202644686288]},
 'Cuba': {'latlon': [22.093377645162377, -79.54124915322569]},
 'Ecuador': {'latlon': [-1.448279428452679, -78.39002628888198]},
 'Emiratos Árabes Unidos': {'latlon': [23.43367363652925, 53.97651207707088]},
 'España': {'latlon': [40.40029669653546, -3.566448279164604]},
 'Estados Unidos': {'latlon': [39.6892552859029, -106.71056584313902]},
 'Francia': {'latlon': [46.62237366531258, 2.449486512892406]},
 'Grecia': {'latlon': [39.47499718996852, 22.581857843165096]},
 'Guayana': {'latlon': [5.095633556179767, -58.23109466184257]},
 'Irlanda': {'latlon': [53.17669234237786, -8.138264403779033]},
 'Irlanda del Norte': {'latlon': [54.608054501614106, -6.694093563067327]},
 'Israel': {'latlon': [31.028641443248148, 34.657992593483584]},
 'Italia': {'latlon': [45.23561638578775, 9.581412900784926]},
 'Japón': {'latlon': [36.65362538180608, 139.26813805372842]},
 'Letonia': {'latlon': [56.633417305664295, 26.40511559780674]},
 'México': {'latlon': [23.940958892339154, -102.50662121099992]},
 'Panamá': {'latlon': [9.074346360995946, -78.63576391647143]},
 'Paraguay': {'latlon': [-23.227518831328837, -58.39842286262484]},
 'Países Bajos': {'latlon': [52.17235334752911, 5.322768998090964]},
 'Perú': {'latlon': [-13.58782829723799, -71.85199286188094]},
 'Portugal': {'latlon': [39.678798984485695, -7.978030682170072]},
 'Puerto Rico': {'latlon': [18.24291627031706, -66.54144287109375]},
 'Reino Unido de Gran Bretaña': {'latlon': [52.601885382104854,
   -1.460467598400783]},
 'República Checa': {'latlon': [49.73244820552043, 15.31410310187681]},
 'República Dominicana': {'latlon': [18.89926969484071, -70.5003985986163]},
 'República de Azerbaiyán': {'latlon': [40.34583220569192,
   47.659728875987014]},
 'Rusia': {'latlon': [60.06655395370217, 63.152100419498936]},
 'Sudáfrica': {'latlon': [-29.009215741912783, 25.15924152977294]},
 'Suecia': {'latlon': [60.594601666933556, 14.37197706578911]},
 'Suiza': {'latlon': [46.97259012423501, 8.210718017522652]},
 'Turquía': {'latlon': [38.98957968355569, 35.423547472038365]},
 'Uganda': {'latlon': [1.275691289321685, 32.367039930748376]},
 'Uruguay': {'latlon': [-32.800158283377925, -56.017869705722205]},
 'Venezuela': {'latlon': [7.267615149519713, -63.209483297416114]}}

In [32]:
countries['Argentina']['latlon'], countries['Alemania']['latlon']


Out[32]:
([-35.18209766247696, -65.1548248323], [51.0871017663336, 10.370787457775123])

In [53]:
atribution = ('Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> '
              'contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">'
              'CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>')

my_map = folium.Map(location=[45.372, -121.6972],
                   zoom_start=2,
                   tiles='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                   attr=atribution)

# Countries markers
for country in list_countries:
    # Marker
    text = "{0}".format(country)
    folium.Marker(countries[country]['latlon'], 
              popup=text).add_to(my_map)

# Connection lines
for i in count_viajes_x_destino_bloque.itertuples():
    lat = np.linspace(countries[i.origen]['latlon'][0], countries[i.destino]['latlon'][0], 3)
    lon = np.linspace(countries[i.origen]['latlon'][1], countries[i.destino]['latlon'][1], 3)

    # los paises que esta muy juntos los conecto por una recta
    if lat.max() - lat.min() > 5:
        lat[1] = lat[1] + np.random.choice([-1, 1])*(lat.max() - lat.min())/np.random.choice([4, 5])
        lon[1] = lon[1] + np.random.choice([-1, 1])*np.random.random()*15
        f2 = interp1d(lat, lon, kind='quadratic')
        #
        xnew = np.linspace(lat.min(), lat.max(), num=41, endpoint=True)
        coordinates = [[x, y] for x, y in zip(xnew, f2(xnew))]
    else:
        coordinates = [[x, y] for x, y in zip(lat, lon)]

    # Asignamos los colores si estan en los principales bloques
    if i.bloque in colores.keys():
        color = colores[i.bloque]
    else:
        color = colores['otros']

    popup = "Bloque: {0}\nCantidad de viajes: {1}".format(i.bloque, i.count)
    
    html="""
    <div class="line-popup">
        <strong>Bloque:</strong> {0}<br>
        <strong>Cantidad de viajes:</strong> {1}<br>
    </div>
    """.format(i.bloque, i.count)
    iframe = folium.element.IFrame(html=html, width='auto', height='70px;')
    popup = folium.Popup(iframe)
    
    folium.PolyLine(coordinates, weight=1+i.count, color=color, popup=popup).add_to(my_map)

my_map


Out[53]:

In [52]:
my_map.save('index.html')

In [54]:


In [ ]:


In [ ]:


In [58]:
features = []

for country in countries:
    features.append({
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [countries[country]['latlon'][1], countries[country]['latlon'][0]]
            },
            "properties": {
                "name": country
            }
        })
    
data = { "type": "FeatureCollection", "features": features}
with open('countries.geojson', 'a') as f:
    json.dump(data, f, indent=4)

In [85]:
ls = []

lines = []

for i in count_viajes_x_destino_bloque.itertuples():
    lat = np.linspace(countries[i.origen]['latlon'][0], countries[i.destino]['latlon'][0], 3)
    lon = np.linspace(countries[i.origen]['latlon'][1], countries[i.destino]['latlon'][1], 3)

    # los paises que esta muy juntos los conecto por una recta
    if lat.max() - lat.min() > 5:
        lat[1] = lat[1] + np.random.choice([-1, 1])*(lat.max() - lat.min())/np.random.choice([4, 5])
        lon[1] = lon[1] + np.random.choice([-1, 1])*np.random.random()*15
        f2 = interp1d(lat, lon, kind='quadratic')
        #
        xnew = np.linspace(lat.min(), lat.max(), num=41, endpoint=True)
        coordinates = [[y, x] for x, y in zip(xnew, f2(xnew))]
    else:
        coordinates = [[y, x] for x, y in zip(lat, lon)]
    
    # Asignamos los colores si estan en los principales bloques
    if i.bloque in colores.keys():
        color = colores[i.bloque]
    else:
        color = colores['otros']
    
    if i.bloque in bloques_validos:
        capa = i.bloque
    else:
        capa = "otros"
    
    ls.append(capa)
    
    lines.append({
    "type": "Feature",
    "properties": {"color": color,
                  "bloque": i.bloque,
                  "contador": i.count,
                  "capa": capa},
    "geometry": {
        "type": "LineString",
        "coordinates": coordinates
    }
    })

with open('connections.js', 'a') as f:
    f.write("var connections = {0};".format(str(lines).replace("'", '"')))

In [87]:
set(ls)


Out[87]:
{'Frente Cívico por Santiago',
 'Frente Pro',
 'Justicialista San Luis',
 'Movimiento Popular Neuquino',
 'PJ Frente para la Victoria',
 'PJ La Pampa',
 'Partido Socialista',
 'Unión Cívica Radical',
 'otros'}

In [90]:
for i in list(set(ls)):
    print(i, colores[i])


Unión Cívica Radical #ED1C24
Frente Pro #FFD700
otros #ff7f00
Justicialista San Luis #add8e6
Movimiento Popular Neuquino #4169e1
Partido Socialista #fdbf6f
Frente Cívico por Santiago #E60026
PJ La Pampa #318CE7
PJ Frente para la Victoria #0000ff

In [89]:
colores


Out[89]:
{'Frente Cívico por Santiago': '#E60026',
 'Frente Pro': '#FFD700',
 'Justicialista San Luis': '#add8e6',
 'Movimiento Popular Neuquino': '#4169e1',
 'PJ Frente para la Victoria': '#0000ff',
 'PJ La Pampa': '#318CE7',
 'Partido Socialista': '#fdbf6f',
 'Unión Cívica Radical': '#ED1C24',
 'otros': '#ff7f00'}

In [ ]: