Suite

Créer un graphique routable à partir du fichier de formes Point and Line à l'aide de Networkx ?


J'ai un fichier de formes qui comprend toutes les rues de la zone d'étude et un autre fichier de formes qui contient des points représentant les origines et les destinations.

Est-il possible de trouver le chemin le plus court entre toutes les origines et destinations, en utilisant les liens du fichier de formes de liens ?

J'utilise principalement Python, Networkx et QGIS pour mon travail, il serait donc formidable d'utiliser ces outils pour cette tâche.


Le problème initial le plus difficile à résoudre est le co-enregistrement de vos données ponctuelles avec votre réseau. Ces données peuvent provenir de différentes sources, et donc une erreur de position est à prévoir. En l'absence de règles plus complexes régissant la localisation des points dans le réseau, vous pouvez utiliser le point le plus proche du réseau pour chaque origine/destination, comme indiqué dans cette réponse existante. Le défi ici est de trouver l'emplacement le plus proche le long de la ligne, pas seulement le sommet le plus proche :

Une fois cette étape terminée, vous devriez avoir votre réseau d'origine et les points nouvellement co-enregistrés. À partir de là, vous pouvez utiliser la fonction nx_shp de NetworkX pour importer le fichier de formes dans un modèle de graphique.

Et bien que cela ne soit pas documenté, si vous jetez un œil à la source, vous verrez que si vous créez un fichier de formes avec deux couches, une de points et une de lignes, il utilisera vos points comme nœuds et les lignes comme les bords, ce qui peut être utile.


QGIS 1.8 a une classe intégrée appelée qgis.networkanalysis, il a des fonctions pour lier des points aux lignes et calculer le chemin le plus court.


Lecture de shp à l'aide de networkx, les bords parallèles manquent d'attributs

J'essaie d'utiliser networkx.read_shp pour créer un MultiGraph à partir d'un fichier de forme. Je comprends que la fonction doit être modifiée car elle crée généralement un DiGraph que j'essaie en essayant ceci:

Le reste de la fonction reste le même. Lors de la vérification d'eges, je peux voir que lorsqu'il y a des bords parallèles, l'un d'eux semble avoir un dictionnaire vide au lieu des attributs (bien que ceux-ci soient présents dans le fichier de formes). J'ai déjà vu une question similaire, mais il semble utiliser une version obsolète de networkx. Existe-t-il un moyen de créer un multigraphe ayant des arêtes parallèles avec leurs attributs ? J'ai vu cette réponse NetworkX - Comment créer MultiDiGraph à partir de Shapefile ? mais c'est pour un orienté, je peux essayer de le convertir après mais s'il existe une solution plus directe elle serait appréciée.


TypeError : type non hachable : 'LineString' lors de l'utilisation de ox.simplify_graph()

J'ai un ensemble de données à partir duquel j'ai construit un graphique compatible NetworkX. Un fichier de formes a été converti en dictionnaires pour les nœuds et les arêtes, qui ont ensuite été convertis en GeoDataFrame . À partir de là, j'ai utilisé ox.graph_from_gdfs() pour créer un graphique fonctionnel. Le bord GeoDataFrame ressemble à ceci (première rangée, simplifiée) :

tandis que le nœud GeoDataFrame ressemble à ceci :

Les convertir en MultiDiGraph ne renvoie aucune erreur :

Les mêmes données sont également renvoyées lors de la reconversion du graphique en gdfs.

Cependant, lors de la simplification de G, l'erreur suivante est générée :

Je suppose que certaines parties des données dans gdf_nodes et gdf_edges ne sont pas au bon format ou qu'il manque quelque chose. Cependant, je ne peux pas comprendre quoi. Je n'ai rencontré aucune autre erreur avec OSMnx en dehors de l'utilisation de cette fonction.

Voici un code simple pour reproduire l'erreur

Je soupçonne qu'il existe des nœuds dupliqués avec des identifiants différents (voir x, y pour 111603 et 111604). Peut-être que cela pourrait être le problème?


Analyse de réseau en Python¶

Trouver le chemin le plus court en utilisant un réseau routier spécifique est un problème SIG courant qui a de nombreuses applications pratiques. Par exemple, les navigateurs font partie de ces applications « quotidiennes » où routage l'utilisation d'algorithmes spécifiques est utilisée pour trouver l'itinéraire optimal entre deux (ou plusieurs) points.

Il est également possible d'effectuer des analyses de réseau telles que le routage de tranposrtation en Python. Networkx est un module Python qui fournit des outils pour analyser les réseaux de différentes manières. Il contient également des algorithmes tels que l'algorithme de Dijkstra ou l'algorithme A* qui sont couramment utilisés pour trouver les chemins les plus courts le long du réseau de transport.

Pour pouvoir effectuer des analyses de réseau, il est bien entendu nécessaire de disposer d'un réseau utilisé pour les analyses. Le package OSMnx que nous venons d'explorer dans le didacticiel précédent permet de récupérer très facilement des réseaux routables à partir d'OpenStreetMap avec différents modes de transport (marche, vélo et conduite). OSMnx combine également certaines fonctionnalités du module networkx pour faciliter le routage le long des données OpenStreetMap.

Ensuite, nous testerons les fonctionnalités de routage d'OSMnx en trouvant le chemin le plus court entre deux points en fonction des routes carrossables. Avec de petites modifications, il est également possible de répéter l'analyse pour le réseau de rues piétonnes.


Créer un graphique routable à partir du fichier de formes Point and Line à l'aide de Networkx ? - Systèmes d'information géographique

C'est l'une des plus de 100 recettes gratuites du livre de recettes IPython, deuxième édition, de Cyrille Rossant, un guide sur l'informatique numérique et la science des données dans le Jupyter Notebook. L'ebook et le livre imprimé sont disponibles à l'achat chez Packt Publishing.

14.7. Création d'un planificateur d'itinéraire pour un réseau routier

Dans cette recette, nous nous appuyons sur plusieurs techniques décrites dans les recettes précédentes afin de créer un simple planificateur d'itinéraire de type GPS en Python. Nous récupérerons les données du réseau routier californien auprès du Bureau du recensement des États-Unis afin de trouver les chemins les plus courts dans le graphique du réseau routier. Cela nous permettra d'afficher des itinéraires routiers entre deux endroits en Californie.

Vous avez besoin de Smopy pour cette recette. Vous pouvez l'installer avec pip install git+https://github.com/rossant/smopy . Pour que NetworkX puisse lire les ensembles de données Shapefile, vous avez également besoin de GDAL/OGR. Vous pouvez l'installer avec conda install gdal .

Au moment d'écrire ces lignes, gdal ne semble pas bien fonctionner avec conda et Python 3.6. Vous devrez peut-être rétrograder Python vers Python 3.5 avec conda install python=3.5 .

  1. Nous chargeons les données (un ensemble de données Shapefile) avec NetworkX. Cet ensemble de données contient des informations détaillées sur les routes principales en Californie. La fonction read_shp() de NetworkX renvoie un graphique, où chaque nœud est une position géographique, et chaque bord contient des informations sur la route reliant les deux nœuds. Les données proviennent du site Web du Bureau du recensement des États-Unis à l'adresse http://www.census.gov/geo/maps-data/data/tiger.html.
  1. Ce graphe n'est pas nécessairement connexe, mais nous avons besoin d'un graphe connexe pour calculer les chemins les plus courts. Ici, nous prenons le plus grand sous-graphe connecté en utilisant la fonction connected_component_subgraphs() :
  1. Nous définissons deux positions (avec la latitude et la longitude) et trouvons le chemin le plus court entre ces deux positions :
  1. Chaque bord du graphique contient des informations sur la route, y compris une liste de points le long de cette route. Nous créons d'abord une fonction qui renvoie ce tableau de coordonnées, pour n'importe quelle arête du graphe :
  1. On peut notamment utiliser le chemin routier pour calculer sa longueur. Nous devons d'abord définir une fonction qui calcule la distance entre deux points quelconques en coordonnées géographiques :
  1. Nous mettons à jour notre graphique en calculant la distance entre deux nœuds connectés. On ajoute cette information avec l'attribut distance des arêtes :
  1. La dernière étape avant de trouver le chemin le plus court dans le graphe consiste à trouver les deux nœuds du graphe qui sont les plus proches des deux positions demandées :
  1. Maintenant, nous utilisons la fonction shortest_path() de NetworkX pour calculer le chemin le plus court entre nos deux positions. Nous spécifions que le poids de chaque bord est la longueur de la route entre eux :
  1. L'itinéraire a été calculé. La variable path contient la liste des arêtes qui forment le chemin le plus court entre nos deux positions. Maintenant, nous pouvons obtenir des informations sur l'itinéraire avec les pandas. L'ensemble de données comporte quelques champs d'intérêt, notamment le nom et le type (État, autoroute, etc.) des routes :

Voici la longueur totale de cet itinéraire :

  1. Notre chemin contient des nœuds connectés dans le graphe. Chaque arête entre deux nœuds est caractérisée par une liste de points (constituant une partie de la route). Par conséquent, nous devons définir une fonction qui concatène les positions le long de chaque bord du chemin. Nous devons concaténer les positions dans le bon ordre le long de notre chemin. Nous choisissons l'ordre en fonction du fait que le dernier point d'une arête doit être proche du premier point de l'arête suivante :

Nous avons calculé le chemin le plus court avec la fonction shortest_path() de NetworkX. Ici, cette fonction utilisée Algorithme de Dijkstra. Cet algorithme a une grande variété d'applications, par exemple dans les protocoles de routage réseau.

Il existe différentes manières de calculer la distance géographique entre deux points. Ici, nous avons utilisé une formule relativement précise : la distance orthodromique (aussi appelé distance orthodromique), qui suppose que la Terre est une sphère parfaite. On aurait aussi pu utiliser une formule plus simple puisque la distance entre deux points successifs sur une route est petite.

Vous pouvez trouver plus d'informations sur les problèmes du chemin le plus court et l'algorithme de Dijkstra dans les références suivantes :


Modules de collaboration d'entreprise et modules d'analyse de journaux puissants

Une bibliothèque Java open source pour la correspondance de cartes en ligne et hors ligne avec OpenStreetMap. Avec son ensemble complet de fonctions géométriques et spatiales, une structure de données cartographiques en mémoire et des fonctions d'apprentissage automatique de base, il s'agit d'une base polyvalente pour les services évolutifs basés sur la localisation et l'analyse de données spatio-temporelles sur la carte. Il est conçu pour être utilisé dans des systèmes parallèles et distribués et, par conséquent, comprend un serveur de correspondance de carte autonome et peut être utilisé dans des systèmes distribués pour des services de correspondance de carte dans le cloud. Barefoot se compose d'une bibliothèque de logiciels et d'un serveur cartographique (basé sur Docker) qui permet d'accéder aux données de carte routière d'OpenStreetMap et est flexible pour être utilisé dans des infrastructures cloud distribuées en tant que serveur de données cartographiques ou côte à côte avec les serveurs autonomes de Barefoot pour la correspondance hors ligne (serveur de correspondance) et en ligne (serveur de suivi) ou d'autres applications construites avec la bibliothèque Barefoot. L'accès aux données cartographiques est fourni avec une structure de données cartographiques en mémoire rapide et flexible. Avec GeographicLib [1] et l'API de géométrie d'ESRI [2], il fournit un ensemble complet d'opérations géographiques et géométriques pour l'analyse des données spatiales sur la carte.


Magellan est un moteur d'exécution distribué pour l'analyse géospatiale sur les mégadonnées. Il est implémenté sur Apache Spark et exploite profondément les techniques de base de données modernes telles que la disposition efficace des données, la génération de code et l'optimisation des requêtes afin d'optimiser les requêtes géospatiales. Le développeur d'applications écrit des requêtes SQL standard ou des trames de données pour évaluer les expressions géométriques tandis que le moteur d'exécution s'occupe de disposer efficacement les données en mémoire pendant le traitement des requêtes, en choisissant le bon plan de requête, en optimisant l'exécution de la requête avec des indices spatiaux bon marché et efficaces tout en présentant un abstraction déclarative au développeur.

GoJS est une bibliothèque JavaScript et TypeScript permettant de créer et de manipuler des diagrammes, des graphiques et des graphiques. GoJS est une bibliothèque flexible qui peut être utilisée pour créer différents types de diagrammes interactifs, notamment des visualisations de données, des outils de dessin et des éditeurs de graphiques. Il existe des exemples d'organigramme, d'organigramme, de processus métier BPMN, de couloirs, de chronologies, de graphiques d'état, de kanban, de réseau, de carte mentale, de sankey, d'arbres généalogiques et de génogrammes, de diagrammes en arête de poisson, de plans d'étage, UML, d'arbres de décision, de graphiques pert, de Gantt, et des centaines d'autres. GoJS comprend un certain nombre de dispositions intégrées, notamment une disposition en arborescence, une disposition de digraphe dirigée, radiale et en couches, ainsi qu'un certain nombre d'exemples de disposition personnalisés.


Sections manquantes et mouvements inverses dans STMATCH #70

Salut,
J'utilise l'API python (compilée en python3) et STMATCH.
Les choses semblent prometteuses, cependant, je n'obtiens pas de correspondances parfaites des données : j'obtiens soit des liens manquants, soit des mouvements inverses inutiles (et/ou les deux).

J'ai créé un exemple autonome pour le comportement ici :
https://github.com/cweber9843/test_fmm/blob/master/test_fmm_on_synthetic_data.ipynb
Incluant une variation de paramètre et une vérification du réseau.

  • Quelle est la meilleure façon de régler les paramètres ?
  • Peut-être construire un minimiseur autour d'eux ? Une sorte de recherche de dégradé ?
  • Comment éviter les mouvements inverses ?
  • Comment garantir un match connecté ?
  • Existe-t-il des articles disponibles pour l'algorithme STMATCH ?
  • Dans le document FMM, une pénalité est mentionnée pour éviter le mouvement inverse. Est-ce toujours appliqué ?
  • FMM avec un fichier UBODT précalculé donnera-t-il de meilleurs résultats ?
  • Comment se fait la visualisation du réseau (ex. ici : #30) ? Est-ce un plugin QGis ?
  • d'autres astuces ?

Le texte a été mis à jour avec succès, mais ces erreurs se sont produites :

Nous ne sommes pas en mesure de convertir la tâche en problème pour le moment. Veuillez réessayer.

Le problème a été créé avec succès, mais nous ne sommes pas en mesure de mettre à jour le commentaire pour le moment.

Cyang-kth a commenté le 14 mai 2020 •

Le meilleur moyen serait d'étiqueter manuellement un sous-ensemble de trajectoires, puis d'essayer divers paramètres pour améliorer autant que possible la précision.

La formation hyper-paramétrique est préférable d'être mise en œuvre à l'extérieur du programme actuel.

Soit vous effectuez un prétraitement pour lisser la trajectoire afin de supprimer le mouvement inverse (comme dans l'exemple que vous montrez), soit (modifiez en fait le programme), cela est principalement dû à l'hypothèse que le véhicule doit se déplacer dans la direction d'un bord. (Une façon est d'ajouter une tolérance pour le mouvement inverse)

Une correspondance échoue si le chemin ne peut pas être connecté (dans l'exemple, je pense qu'il est probable que certains bords du réseau soient dirigés plutôt que bidirectionnels.).

Le papier est ici https://dl.acm.org/doi/abs/10.1145/1653771.1653820
Lou Y, Zhang C, Zheng Y et al. Map-matching pour les trajectoires GPS à faible taux d'échantillonnage[C]//Actes de la 17ème conférence internationale ACM SIGSPATIAL sur les avancées des systèmes d'information géographique. 2009 : 352-361.

FMM est assez similaire à celui-ci sauf que le précalcul est utilisé.

  • Dans le document FMM, une pénalité est mentionnée pour éviter le mouvement inverse. Est-ce toujours appliqué ?

Non, cela a été supprimé de l'implémentation actuelle car il est rarement utilisé.

Je ne pense pas que FMM et STMATCH suivent le même principe mais on utilise le précalcul et l'autre non.

Il est directement visualisé dans QGIS sans plugin externe. Vous venez de définir un symbole de ligne dirigée.

Je vous recommanderais d'abord de jeter un œil au réseau dans QGIS. Certaines parties peuvent ne pas être connectées.

Cweber9843 a commenté le 14 mai 2020

Merci pour la réponse rapide!
Je viens de réaliser que mon problème pouvait vraiment provenir du réseau : afin d'obtenir des liens dirigés, j'ai dupliqué les coordonnées d'origine et échangé source/cible, mais sans réellement inverser la ligne. Je suppose que pour un vrai réseau dirigé, je devrai inverser la géométrie. Merci de m'avoir poussé dans la bonne direction !

Cweber9843 a commenté le 14 mai 2020

Merci encore pour vos commentaires, le problème était bien dans le réseau. J'ai maintenant inversé chaque géométrie, et maintenant le réseau est vraiment bidirectionnel, et non seulement les paires source-cible sont échangées avec la même direction dans la géométrie.

Maintenant, STMATCH trouve de manière fiable de bonnes correspondances, il y a peu de mouvements inverses et dans mon échantillon de test, je ne vois qu'une seule correspondance faussement positive. L'algorithme est également beaucoup moins sensible aux paramètres.
Je peux maintenant passer à des pistes plus réalistes et faire plus de tests là-bas.

Cweber9843 commenté le 15 mai 2020

Désolé, encore une question, et je rouvre ce problème car je pense qu'il est un peu lié à mon réseau, mais je ne vois pas l'erreur :
Lorsque j'exécute votre exemple de bloc-notes pour STMATCH, j'obtiens les mêmes résultats que l'exemple, en particulier j'obtiens un résultat pour cpath.
Pour mes propres données et réseau, cependant, je n'obtiens que les données ponctuelles, pas les bords :

Pour la ligne verte du tracé, je recherche les identifiants de périphérie dans mon réseau, mais je pense que cela génère des artefacts, tels que l'extrémité inférieure de la ligne verte dans la figure ci-dessus.

Avez-vous des indices sur la raison pour laquelle je n'obtiens pas de cpath ?
Je n'ai pas (encore) créé mon shapefile comme vous l'avez décrit, via postGIS, mais plutôt via geopandas et networkX.

Cyang-kth commenté le 15 mai 2020

La raison pour laquelle vous avez un opath mais un cpath vide est qu'il y a deux points appariés qui ne sont pas connectés au réseau.

Si vous pouvez réellement extraire cette trajectoire unique dans un fichier séparé traj.csv, puis l'exécuter avec un niveau de journalisation de 0, vous pouvez alors voir un journal plus détaillé du processus de correspondance de carte, qui peut indiquer que certains points ne sont pas connectés.

Le fichier journal peut contenir des centaines de milliers de lignes, vous pouvez d'abord l'exporter dans un fichier journal puis vérifier ce journal

Cweber9843 commenté le 19 mai 2020

@cyang-kth , merci encore pour la réponse rapide.

J'ai maintenant exécuté stmatch à partir de la ligne de commande, sur un réseau WGS84 et des données (UTM32 a donné une erreur SQLite sans colonne de ce type : date de publication - voulez-vous un rapport de bogue à ce sujet ? L'API python s'exécute indépendamment du CRS.).

Cependant, je ne vois pas plus d'informations sur les points qui ne sont pas connectés :
Contenu de stmatch.log :
[info][stmatch_app_config.cpp:48 ] Commencer à lire la configuration stmatch à partir des arguments [info][stmatch_app_config.cpp:105] Terminer par la lecture de la configuration stmatch arg [info][stmatch_app_config.cpp:109] ---- Imprimer la configuration -- -- [info][network_config.cpp:6 ] NetworkConfig [info][network_config.cpp:7 ] Nom de fichier : ./data/bike_centerline_v1_extract_ANVedges_source_target_rev_renamed_mini_WGS84.shp [info][network_config.cpp:8 ] Nom d'identification : id [info] [network_config.cpp:9 ] Nom de la source : source [info][network_config.cpp:10 ] Nom de la cible : cible [info][gps_config.cpp:19 ] Format GPS : point CSV [info][gps_config.cpp:20 ] Nom de fichier : ./data/syntetic_data_ANV_WGS84.csv [info][gps_config.cpp:21 ] Nom d'identification : id [info][gps_config.cpp:22 ] x nom : x [info][gps_config.cpp:23 ] y nom : y [info][gps_config.cpp:24 ] Nom de l'horodatage : timestamp [info][result_config.cpp:30 ] ResultConfig [info][result_config.cpp:31 ] Fichier : mr.txt [info][result_config.cpp : 32 ] Champs : opath cpath mgeom [info][stmatch_algorithm.c pp:22 ] STMATCHAlgorithmConfig [info][stmatch_algorithm.cpp:23 ] k 4 rayon 0,4 gps_error 0,5 vmax 80 facteur 1,5 [info][stmatch_app_config.cpp:114] Log level 0-trace [info][stmatch_app_config.cpp:115] Étape 1 [info][stmatch_app_config.cpp:116] Utiliser omp false [info][stmatch_app_config.cpp:117] ---- Imprimer la configuration terminée ---- [warning][result_config.cpp:167] Écraser le fichier de résultat existant mr.txt [info][network.cpp:37 ] Lire le réseau à partir du fichier ./data/bike_centerline_v1_extract_ANVedges_source_target_rev_renamed_mini_WGS84.shp [info][network.cpp:130] Nombre de bords 60 nœuds 28 [info][network.cpp:131] Index de champ : id 2 source 4 cible 5 [info][network.cpp:134] Lire le réseau terminé. [info][network_graph.cpp:17 ] Construire le graphe à partir des bords du réseau start [info][network_graph.cpp:30 ] Nœuds du graphe 28 bords 60 [info][network_graph.cpp:31 ] Construire le graphe à partir des bords du réseau end [info] [gps_reader.cpp:239] Id index 0 x index 1 y index 2 time index 3 [info][stmatch_app.cpp:33 ] Rapport de progression étape 1 [info][stmatch_app.cpp:35 ] Commencer à faire correspondre les trajectoires [info] [stmatch_app.cpp:64 ] Exécuter la correspondance de carte dans un seul thread [info][stmatch_app.cpp:67 ] Progression 0 [info][stmatch_app.cpp:81 ] Processus MM terminé [info][stmatch_app.cpp:87 ] Le temps prend 0,002 [info][stmatch_app.cpp:88 ] Temps sans l'entrée 0 [info][stmatch_app.cpp:89 ] Terminer le match sur la carte total des points 26 correspondants 0 [info][stmatch_app.cpp:91 ] Pourcentage correspondant : 0 [info ][stmatch_app.cpp:92 ] Vitesse de match de point : 0 [info][stmatch_app.cpp:93 ] Vitesse de match de point (hors entrée) : -nan [info][stmatch_app.cpp:95 ] Le temps prend 0,002
Et mr.txt :
idopathcpathmgeom 12312150,12149,10902,10902,10902,10902,10902,11310,11309,11309,10122,10122,10122,10122,9381,9381,9381,9009,9764,9009,9009,9009,9009,9009,9009 ,9009LINESTRING()

Je suis assez confiant que mon réseau est connecté et bidirectionnel maintenant :

Les nombres en vert et en rouge sont respectivement les nœuds source et cible, et les nombres en noir sont l'identifiant de bord. Tous les bords sont bidirectionnels et tous semblent être connectés (par exemple, le nœud 126 est la source du bord 154, mais est la cible du 362). J'ai vérifié cela pour tous les bords dans cet exemple.
bike_centerline_v1_extract_ANVedges_source_target_rev_renamed_mini_WGS84.shp


Une recette pour passer automatiquement des données au texte aux diapositives Reveal.js

Au cours des dernières années, j'ai expérimenté par intermittence diverses recettes pour créer des rapports de texte à partir d'ensembles de données tabulaires (des plugins de tableur commencent également à apparaître dans un objectif similaire). Il y a plusieurs problèmes associés à cela, notamment:

  • identifier les données ou les informations que vous souhaitez signaler à partir de votre ensemble de données
  • (dérivant automatiquement les informations)
  • construire des phrases appropriées à partir des données
  • organiser les phrases dans une sorte de structure narrative
  • faire en sorte que les phrases se lisent bien ensemble.

Une autre approche pour humaniser le rapport de données tabulaires consiste à générer des pages Web modélisées qui examinent et rendent compte du contenu d'un ensemble de données. Cela présente certaines similitudes avec les rapports de style tableau de bord, mélangeant des tableaux et des graphiques, bien qu'un simple modèle de texte puisse également être généré pour remplir le page.

Dans un contexte commercial, le reporting se fait souvent via des présentations Powerpoint. Les diapositives de la plate-forme de présentation peuvent inclure du contenu extrait d'une feuille de calcul modèle, qui elle-même peut générer automatiquement des tableaux et des graphiques pour une telle réutilisation à partir d'un nouvel ensemble de données. Dans ce cas, la recette peut ressembler à quelque chose comme :

Dans les deux articles précédents, l'observateur d'entre vous a peut-être remarqué que j'avais exploré quelques composants pour une recette qui peut être utilisée pour générer des présentations basées sur le navigateur révélation.js à partir des 20% qui représentent les 80%.

L'ensemble de données avec lequel j'ai bricolé est un ensemble de données mensuelles sur les dépenses de transparence du Conseil de l'île de Wight. Les versions récentes ont la forme :

Ainsi, comme indiqué précédemment, il est possible d'utiliser le type de processus suivant pour générer automatiquement des diaporamas révélation.js à partir d'un bloc-notes Jupyter avec des cellules de diapositive correctement configurées (en fait, des cellules normales avec un ensemble d'éléments de métadonnées approprié) utilisées comme représentation intermédiaire .

Il y a un exemple de diaporama basé sur les données d'octobre 2016 ici. Notez que certaines diapositives ont des “slides”, c'est-à-dire des diapositives sous surveillez les indicateurs fléchés en bas à gauche pour savoir quand ils sont disponibles. Notez également que le défilement est un peu aléatoire – idéalement, une nouvelle diapositive défilerait toujours vers le haut, et pour les fragments insérés dans une diapositive un à la fois, la diapositive devrait défiler vers le bas pour les suivre).

La structure de la présentation est globalement la suivante :

Par exemple, voici une diapositive récapitulative des dépenses par direction, notez que nous pouvons intégrer des graphiques assez facilement. (Les graphiques sont stylisés à l'aide marin, donc une gamme de thèmes alternatifs sont trivialement disponibles). Les éléments distincts de la direction sont introduits un à la fois au fur et à mesure que fragments.

La diapositive suivante passe en revue les dépenses en capital par rapport aux revenus de dépenses pour une direction particulière, ventilées par type de dépenses (les diapositives correspondantes sont générées pour toutes les autres directions). (J'ai également fait une ventilation pour chaque direction par zone de service.)

Les articles répertoriés sont classés par valeur et représentent ensemble au moins 80 % des dépenses dans le domaine correspondant. Tous les autres éléments contribuant à plus de 5 % (?) des dépenses correspondantes sont également répertoriés.

Notez que les sous-diapositives sont disponibles vers le bas de cette diapositive, plutôt que de l'autre côté le secteur glisse dans le pont. Cette structure 1.5D signifie que nous pouvons insérer un élément de conception narrative flexible dans la présentation, donnant au lecteur la possibilité d'explorer les données, mais de manière contrainte.

Dans ce cas, j'ai généré des sous-diapositives pour chaque type de dépenses majeures dans les pots de capital et de revenus, puis j'ai ajouté une ventilation des principaux fournisseurs pour ce domaine de dépenses.

Cela représente juste une première passe pour générer un jeu de diapositives 1.5D à partir d'un jeu de données tabulaire. Une heurstique de Pareto (80/20) est utilisée pour essayer de prioriser les informations affichées afin de représenter 80% des dépenses dans différents domaines, ou d'autres contributions importantes.

L'application répétée de ce principe nous permet d'identifier les principaux domaines de dépenses, puis les principaux fournisseurs au sein de ces domaines de dépenses.

L'étape suivante consiste à examiner d'autres façons de segmenter et de structurer les données afin de produire des rapports qui pourraient réellement être utiles…

Si vous avez des idées, faites-le moi savoir via les commentaires, ou contactez-nous directement…

PS FWIW, il devrait être assez facile d'exécuter n'importe quel autre ensemble de données qui ressemble globalement à l'exemple en haut à travers le même code avec seulement quelques ajustements mineurs…


Visualisation de vol animée

Jusqu'à présent, nous n'avons examiné que les graphiques statiques sans vie avec quelques survols pour plus d'informations. Faisons une visualisation animée qui montre les vols actifs au fil du temps entre Melbourne et Sydney en Australie.

Le document SVG pour ce type de graphique est composé de texte, de lignes et de cercles.

Les parties dynamiques sont les temps et les éléments au sein de la vol groupe et les données pourraient ressembler à ceci :

Pour obtenir une position x pour une heure dynamique, nous devrons créer une échelle de temps pour chaque vol qui mappe ses heures de départ et d'arrivée à une position x sur notre carte. Nous pouvons parcourir nos données au début en ajoutant des objets et des échelles de date afin qu'ils soient plus faciles à utiliser. Moment.js aide beaucoup ici avec l'analyse et la manipulation des dates.

Nous pouvons maintenant passer notre date changeante à xScale() pour obtenir une coordonnée x pour chaque vol.

Boucle de rendu

Les heures de départ et d'arrivée sont arrondies à 5 minutes afin que nous puissions parcourir nos données par incréments de 5 m du premier départ à la dernière arrivée.

Entrer, mettre à jour et quitter

D3 vous permet de spécifier des transformations et des transitions d'éléments lorsque :

  • De nouveaux points de données arrivent (Entrée)
  • Modification des points de données existants (Mise à jour)
  • Les points de données existants sont supprimés (Quitter)

Transitions

Le code ci-dessus restitue une image toutes les 500 ms avec un incrément de temps de 5 minutes :

  • Il met à jour l'heure
  • Crée un nouveau groupe de vols avec un cercle pour chaque vol
  • Met à jour les coordonnées x/y des vols actuels
  • Supprime les groupes de vols à leur arrivée

Cela fonctionne, mais ce que nous voulons vraiment, c'est une transition en douceur entre chacune de ces images. Nous pouvons y parvenir en créant une transition sur n'importe quelle sélection D3 et en fournissant une fonction de durée et d'accélération avant de définir des attributs ou des propriétés de style.

Par exemple, estompons l'opacité de la saisie des groupes de vols.

Faisons disparaître les groupes de vols sortants.

Ajoutez une transition en douceur entre les points x et y.

Nous pouvons également faire passer l'heure entre les incréments de 5 minutes afin qu'elle s'affiche toutes les minutes plutôt que toutes les cinq minutes en utilisant la fonction d'interpolation.


Voir la vidéo: Programming with NetworkX in Python (Octobre 2021).