Autor: Antonio de Jesus Anaya Hernandez, DevOps eng. for the IoPA.
Autor: The internet of Production Alliance, 2023.
Data was collected by "Glyxon labs', as part of the OKW Data Awards program.
The Open Know Where (OKW) Standard is part of the Internet of Production Alliance and its members.
License: CC BY SA
This review is provided as an analysis and recomendations document for the awardees participants of the OKW Data Awards.
import geopandas
import folium
from folium.plugins import HeatMap, MiniMap, FloatImage, Search, LocateControl
import pandas as pd
import os
from datetime import datetime
from scipy.spatial import KDTree
#import base64
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
files = ["3d_printing.geojson", "cnc.geojson", "laser_cutting.geojson","prototyping.geojson","robotics.geojson"]
for filename in files:
print('Filename: \t', str(filename))
print('Format: \t', str(filename.split(sep='.')[1]).upper())
print('Modified: \t', str(datetime.fromtimestamp(os.path.getctime(filename)).strftime('%Y-%m-%d %H:%M:%S')))
print('Size: \t\t', str(os.path.getsize(filename)), ' KB')
Filename: 3d_printing.geojson Format: GEOJSON Modified: 2023-02-17 17:40:43 Size: 609052 KB Filename: cnc.geojson Format: GEOJSON Modified: 2023-02-17 17:40:43 Size: 391684 KB Filename: laser_cutting.geojson Format: GEOJSON Modified: 2023-02-17 17:40:43 Size: 303769 KB Filename: prototyping.geojson Format: GEOJSON Modified: 2023-02-17 17:40:43 Size: 46871 KB Filename: robotics.geojson Format: GEOJSON Modified: 2023-02-17 17:40:43 Size: 200385 KB
os.environ['PROJ_LIB'] = r'C:\Users\ANAYA\anaconda3\envs\okw_data_awards\Library\share\proj'
merged_data = []
for filename in files:
data = geopandas.read_file(filename)
data['type'] = str(filename).split('.')[0]
data = data.drop(columns=['description', 'styleUrl','icon-opacity', 'icon-color', 'icon-scale', 'icon'])
data = data.loc[data.drop_duplicates(subset=['geometry']).index]
merged_data.append(data)
print(data.shape)
print(len(merged_data))
(1178, 3) (865, 3) (596, 3) (105, 3) (469, 3) 5
merged_data.__len__()
5
merged_data[0]
name | geometry | type | |
---|---|---|---|
0 | Impresión 3D Infinity Makers (ELF Maker) | POINT Z (-99.24064 19.01404 0.00000) | 3d_printing |
1 | Impresión 3D y Electrónica. DIAC-3D | POINT Z (-99.24327 18.92853 0.00000) | 3d_printing |
2 | IMPRESIÓN 3D Taller de diseño | POINT Z (-99.20824 18.92575 0.00000) | 3d_printing |
3 | Jart Studio (sucursal) - Impresión 3D | POINT Z (-99.14459 18.87846 0.00000) | 3d_printing |
4 | 3DZone S.A. de C.V. | POINT Z (-99.19289 18.93332 0.00000) | 3d_printing |
... | ... | ... | ... |
1633 | Usina Fab Lab | POINT Z (-51.20268 -30.03210 0.00000) | 3d_printing |
1634 | Adoro Robótica Makerspace | POINT Z (-43.18070 -22.94186 0.00000) | 3d_printing |
1635 | MXPCB | POINT Z (-89.64009 21.04402 0.00000) | 3d_printing |
1636 | FabLab Cuiabá-BR | POINT Z (-47.43440 -23.47281 0.00000) | 3d_printing |
1637 | Oficina Maker | POINT Z (-63.85365 -8.75318 0.00000) | 3d_printing |
1178 rows × 3 columns
geocodes = pd.read_csv('rg_cities1000.csv')
# Create a KDTree from the lat-lon coordinates in the geocodes DataFrame
tree = KDTree(geocodes[['lat', 'lon']])
def get_country_code(latlong):
lat, lon = latlong
_, idx = tree.query([lat, lon])
return geocodes.iloc[idx]['cc']
def get_city(latlong):
lat, lon = latlong
_, idx = tree.query([lat, lon])
return geocodes.iloc[idx]['name']
for data in merged_data:
data['country'] = list(map(get_country_code, data['geometry'].apply(lambda geom: (geom.y, geom.x))))
for data in merged_data:
data['city'] = list(map(get_city, data['geometry'].apply(lambda geom: (geom.y, geom.x))))
for data in merged_data:
data.drop(columns='geometry').groupby('country').size().sort_values(ascending=False)
sns.set()
fig, axes = plt.subplots(5, figsize=(20,20))
for index, data in enumerate(merged_data):
ax = sns.countplot(y='country', data=data.drop(columns='geometry'), order=data['country'].value_counts().index, ax=axes[index])
ax.set_title(data['type'][0].upper())
#ax.axis('off')
ax_x = ax.axes.get_xaxis()
# ax_x.set_visible(False)
x_label = ax_x.get_label()
x_label.set_visible(False)
ax_y = ax.axes.get_yaxis()
y_label = ax_y.get_label()
y_label.set_visible(False)
sns.set()
fig, axes = plt.subplots(5, figsize=(20,20))
for index, data in enumerate(merged_data):
data.drop(columns='geometry').groupby('city').size().sort_values(ascending=False)
top_cities = data['city'].value_counts().nlargest(20).index
ax = sns.countplot(y='city', data=data[data['city'].isin(top_cities)].drop(columns='geometry'), order=top_cities, ax=axes[index])
ax.set_title(data['type'][0].upper())
#ax.axis('off')
ax_x = ax.axes.get_xaxis()
# ax_x.set_visible(False)
x_label = ax_x.get_label()
x_label.set_visible(False)
ax_y = ax.axes.get_yaxis()
y_label = ax_y.get_label()
y_label.set_visible(False)
point_max = max([(data.geometry.y.max(), data.geometry.x.max()) for data in merged_data])
point_min = min([(data.geometry.y.min(), data.geometry.x.min()) for data in merged_data])
main_map = folium.Map(tiles=None, prefer_canvas=False)
# folium.raster_layers.TileLayer(tiles='openstreetmap', name='Basic').add_to(main_map)
main_map.fit_bounds((point_min, point_max))
#colors = ['#E58606','#2F8AC4','#52BCA3','#99C945','#CC61B0','#24796C','#DAA51B','#5D69B1','#764E9F','#ED645A','#CC3A8E','#A5AA99']
colors = ['#7F3C8D','#11A579','#3969AC','#F2B701','#E73F74','#80BA5A','#E68310','#008695','#CF1C90','#f97b72','#4b4b8f','#A5AA99']
layers = []
marker_layer = folium.FeatureGroup(name='Location markers',show=False)
main_map.add_child(marker_layer)
for index, data in enumerate(merged_data):
layers.append(folium.plugins.FeatureGroupSubGroup(marker_layer, data['type'][0].title()))
popup = folium.features.GeoJsonPopup(fields=['name', 'type'],
aliases=['Name:', 'Capability:'],
localize=True,
sticky=False,
labels=False,
style="font-size: 12px;",
)
geojson = folium.GeoJson(data=data,
popup=popup,
marker=folium.Circle(radius=4,
fill_color=colors[index],
opacity=0.4,
color=colors[index],
weight=10),
)
geojson.add_to(layers[index])
main_map.add_child(layers[index])
colors_dict = {
0.1: '#f3e79b',
0.2: '#fac484',
0.3: '#f8a07e',
0.4: '#eb7f86',
0.5: '#ce6693',
0.6: '#a059a0',
0.7: '#5c53a5',
0.8: '#d1eeea',
0.9: '#a8dbd9',
1.0: '#85c4c9'
}
heatmap_layer = folium.FeatureGroup(name='Capabilities heatmap',show=True)
for index, data in enumerate(merged_data):
heatmap_data = [[row['geometry'].y, row['geometry'].x] for index, row in data.iterrows()]
heatmap = HeatMap(heatmap_data,
# gradient=colors_dict,
opacity=0.1,
radius=10,
blur=12)
print(data['type'][0])
heatmap.add_to(heatmap_layer)
main_map.add_child(heatmap_layer)
3d_printing cnc laser_cutting prototyping robotics
chorophlet_geo = geopandas.read_file(r'region_america.json', encoding='utf-8')
chorophlet_geo = chorophlet_geo[['iso_a2','geometry']]
chorophlet_geo = chorophlet_geo.rename(columns = {"iso_a2":"country"})
data_b = merged_data[0]
for index, data in enumerate(merged_data, 1):
data_b = pd.concat([data_b, data])
data_b = data_b.drop_duplicates(subset=['name'])
data_b = data_b.drop(columns='geometry').groupby('country').size().reset_index(name='count')
data_b
country | count | |
---|---|---|
0 | AR | 257 |
1 | BO | 58 |
2 | BR | 454 |
3 | BZ | 2 |
4 | CL | 99 |
5 | CO | 138 |
6 | CR | 13 |
7 | DO | 28 |
8 | EC | 104 |
9 | GT | 28 |
10 | HN | 18 |
11 | JM | 10 |
12 | MX | 1465 |
13 | NI | 7 |
14 | PA | 13 |
15 | PE | 45 |
16 | PR | 18 |
17 | PY | 27 |
18 | SV | 17 |
19 | US | 10 |
20 | UY | 39 |
21 | VE | 35 |
print(data_b.head())
choropleth = folium.Choropleth(geo_data=chorophlet_geo,
data=data_b,
columns=['country', 'count'],
key_on='feature.properties.country',
fill_color='YlOrRd',
fill_opacity=0.5,
line_opacity=0.2,
smooth_factor=0,
Highlight= True,
line_color = "#ffff",
name = "Countries",
show=False,
overlay=True,
nan_fill_color = "White",
legend_name='Count',
)# .add_to(main_map)
for key in choropleth._children:
if key.startswith('color_map'):
del(choropleth._children[key])
country count 0 AR 257 1 BO 58 2 BR 454 3 BZ 2 4 CL 99
style_function = lambda x: {'fillColor': '#ffffff',
'color':'#000000',
'fillOpacity': 0.1,
'weight': 0.1}
highlight_function = lambda x: {'fillColor': '#B7D696',
'color':'#000000',
'fillOpacity': 0.1,
'weight': 0.1}
choropleth_pop = folium.features.GeoJson(data = chorophlet_geo.merge(data_b, on='country'),
style_function=style_function,
control=True,
name='Total locations by country',
highlight_function=highlight_function,
tooltip=folium.features.GeoJsonTooltip(
fields=['country','count'],
aliases=['Country: ','Locations: '],
style=("background-color: white; color: #333333; font-family: arial; font-size: 12px; padding: 10px;")
))
main_map.add_child(choropleth_pop)
main_map.keep_in_front(choropleth_pop)
location_search = Search(
layer=marker_layer,
geom_type="Point",
placeholder="Search by location name",
collapsed=True,
search_label="name",
).add_to(main_map)
logo_url = 'https://github.com/kny5/data_reports/raw/main/assets/img/iopa_logo_okw.png'
logo_size = (10, 10)
icon = folium.features.CustomIcon(logo_url, icon_size=logo_size)
span = 1
float_image = FloatImage(logo_url, bottom=span, left=span, width=logo_size[0], height=logo_size[1])
main_map.add_child(float_image)
minimap = MiniMap()
main_map.add_child(minimap)
loc_ctrl = LocateControl()
main_map.add_child(loc_ctrl)
map_control = folium.LayerControl(collapsed=True)
folium.TileLayer('cartodbpositron', name='Gray', control=False, attr=None).add_to(main_map)
main_map.add_child(map_control)
main_map.save("data_awards_r1.html")
1. Usage: Click on top-right corner click selector to switch on/off the interactive Markers.