ggsql - Une grammaire graphique pour SQL
(opensource.posit.co)- Outil de visualisation fondé sur la syntaxe SQL, qui combine en un seul flux l’interrogation des données et la construction de graphiques via des clauses comme
VISUALIZE,DRAW,PLACE,SCALEetLABEL - Permet d’associer des colonnes à des propriétés visuelles et de composer, par assemblage de couches, des nuages de points, diagrammes en barres, histogrammes, boxplots et éléments d’annotation dans une même structure
- Transmet directement les résultats de requêtes SQL comme entrée de visualisation, et certaines couches récupèrent uniquement des agrégats via une seule exécution de requête SQL, ce qui favorise le traitement de grands volumes de données
- Conçu comme un exécutable compact et ciblé utilisable sans runtime R ou Python, ce qui le rend adapté à l’intégration avec des outils de reporting orientés code et des assistants d’analyse IA
- La version actuelle est une alpha-release, avec des extensions prévues comme un writer haute performance, des thèmes, l’interactivité, un language server, un formatter et la prise en charge des données spatiales
Présentation de ggsql
- ggsql est une implémentation de la grammar of graphics fondée sur la syntaxe SQL, qui ajoute à SQL des capacités de visualisation structurées
- Utilisable dans Quarto, les notebooks Jupyter, Positron, VS Code, etc.
- Conçu pour permettre aux utilisateurs SQL d’écrire du code de visualisation d’une manière familière
- La structure déclarative et composable des clauses SQL est appliquée aussi à la grammaire de visualisation
- Présente les motivations et des exemples d’usage, tout en développant la syntaxe centrale de ggsql
Exemples de base
-
Premier graphique
- Il est possible de créer un nuage de points avec le jeu de données intégré
penguinsVISUALIZE bill_len AS x, bill_dep AS y FROM ggsql:penguinsDRAW point
- Dans
VISUALIZE, les colonnes de données sont associées à des propriétés visuelles, etDRAW pointcrée une couche de points à partir de cette association de base - Le simple ajout de
species AS colorpermet d’appliquer une distinction par catégories de couleurVISUALIZE bill_len AS x, bill_dep AS y, species AS color FROM ggsql:penguinsDRAW point
- L’ajout de
DRAW smoothpermet de superposer une couche de régression au-dessus de la couche de points- L’association de couleur par espèce est conservée, ce qui génère une ligne distincte pour chaque espèce
- L’approche adopte une composition de composants modulaires plutôt qu’un type de graphique prédéfini
- Il est possible de basculer vers une visualisation totalement différente tout en conservant la même structure
VISUALIZE island AS x, species AS color FROM ggsql:penguinsDRAW bar
- Il est possible de créer un nuage de points avec le jeu de données intégré
-
Exemple complet
- La partie supérieure correspond à une requête SQL classique, et la partie après
VISUALIZEà une requête de visualisation- Dans l’exemple, le backend utilisé est DuckDB
- La partie SQL utilise
astronauts.parquet, avecROW_NUMBER()etQUALIFY, pour ne conserver que la mission la plus récente pour chaque nom - Les deux ensembles sont ensuite combinés
year_of_selection - year_of_birthest calculé commeage, avec l’attribution de la catégorieAge at selectionyear_of_mission - year_of_birthest calculé commeage, avec l’attribution de la catégorieAge at mission- Les deux résultats sont fusionnés avec
UNION ALL
- Dans la requête de visualisation,
age AS xetcategory AS fillsont associés avant d’utiliserDRAW histogramSETTING binwidth => 1, position => 'identity'est spécifié
PLACE ruleajoute une annotation à la position moyenne précalculéex => (34, 44),linetype => 'dotted'
PLACE textajoute des annotations textuellesx => (34, 44, 60)y => (66, 49, 20)- Les libellés incluent
Mean age at selection = 34,Mean age at mission = 44,John Glenn was 77 on his last mission - the oldest person to travel in space! hjust => 'left',vjust => 'top',offset => (10, 0)sont spécifiés
SCALE fill TO accentconvertit les valeurs associées àfillvers la palette de couleursaccent- La clause
LABELcontrôle le titre, le sous-titre, le libellé de l’axe x et celui de la légende- Titre :
How old are astronauts on their most recent mission? - Sous-titre :
Age of astronauts when they were selected and when they were sent on their mission - Axe x :
Age of astronaut (years) fill => null
- Titre :
- La partie supérieure correspond à une requête SQL classique, et la partie après
Structure d’une requête de visualisation
- Avant
VISUALIZE, il s’agit de SQL pur, et la table de résultat n’est pas renvoyée sous forme tabulaire mais transmise directement comme entrée de visualisation - Les tables ou CTE créées dans la partie SQL peuvent être référencées dans la requête de visualisation
- Si les données sont déjà sous une forme adaptée à la visualisation, la partie SQL peut être omise
VISUALIZE year_of_selection AS x, year_of_mission AS y FROM 'astronauts.parquet'
VISUALIZEouVISUALISEmarque la fin de la requête SQL et le début de la requête de visualisation- Les associations relient les colonnes à des propriétés visuelles, c’est-à-dire aux aesthetics
- Dans l’exemple,
agecorrespond à la position sur l’axe x etcategoryà la couleur de remplissage
- Dans l’exemple,
DRAWajoute une couche à la visualisation- Il existe des types simples comme
point, et d’autres commehistogramqui nécessitent des calculs d’agrégation par intervalles - Les couches sont rendues dans l’ordre où elles sont définies
- Il existe des types simples comme
PLACEest une clause sœur deDRAW, dédiée aux annotations, qui utilise des valeurs littérales au lieu de données tabulaires- La visualisation d’exemple se compose de trois couches : une couche d’histogramme, une couche d’annotation par ligne de repère et une couche d’annotation textuelle
- Une couche ne correspond pas nécessairement à un seul objet graphique, et peut rendre plusieurs objets individuels du même type
SCALEest une clause qui convertit les valeurs de données vers des valeurs adaptées à l’aesthetic- Au-delà de la conversion de catégories textuelles en couleurs réelles, elle permet aussi des transformations continues, la définition de breakpoints et la configuration de types d’échelle comme ordinal ou binned
LABELpermet d’ajouter et de modifier des libellés textuels, comme le titre, le sous-titre, les titres d’axes ou de légende
Prendre un peu de recul
- L’exemple ci-dessus contient beaucoup de syntaxe, mais couvre en une seule fois les éléments importants de la grammaire centrale
- De nombreuses requêtes de visualisation peuvent être bien plus simples
- Un exemple de boxplot par sexe pour l’année de naissance est présenté avec
astronauts.parquetVISUALIZE sex AS x, year_of_birth AS y FROM 'astronauts.parquet'DRAW boxplot
- Le code peut être plus long que dans d’autres systèmes de tracé, mais il possède un caractère plus structuré, composable et auto-descriptif
- Ces caractéristiques facilitent l’appropriation du comportement de tous types de graphiques par les utilisateurs, et sont aussi avantageuses pour les futurs assistants de codage LLM
- Il est facile de transformer la même relation en nuage de points avec jitter
DRAW pointSETTING position => 'jitter'
- Il est possible de faire en sorte que le jitter suive la distribution des données pour lui donner le caractère d’un violin plot
SETTING position => 'jitter', distribution => 'density'
- Cette structure syntaxique et cette composabilité facilitent les itérations en analyse exploratoire et en conception de visualisations
Pourquoi ggsql
- Cinq raisons sont avancées pour expliquer le développement de ggsql
- Soutenir les analystes de données et data scientists qui travaillent principalement en SQL
- La forte compatibilité entre SQL et la grammar of graphics
- Construire un outil de visualisation puissant orienté code sans dépendre d’un langage de programmation complet comme R ou Python
- Les excellentes capacités des LLM avec SQL et les possibilités de nouvelles interfaces de visualisation
- Appliquer 18 années d’expérience de développement de ggplot2 sur de nouvelles bases
-
Bonjour, utilisateur SQL
- Pendant que R et Python attiraient l’attention durant la révolution de la data science, SQL a continué de jouer le rôle de socle fiable pour le travail sur les données
- De nombreux professionnels de la donnée utilisent exclusivement SQL, ou principalement SQL
- Pour eux, les options de visualisation existantes sont jugées globalement sous-optimales selon le texte
- Exporter les données pour utiliser R ou Python
- Utiliser des outils BI à interface graphique qui prennent mal en charge la reproductibilité
- Utiliser des outils de visualisation directement dans les requêtes, mais jugés insuffisamment puissants ou ergonomiques
- La syntaxe de ggsql est conçue pour être immédiatement compréhensible par un utilisateur SQL
- Elle exploite les attentes liées à des clauses composables et déclaratives
- ggsql ne vise pas seulement à améliorer la visualisation, mais aussi à attirer les utilisateurs SQL vers l’écosystème de création et de partage de rapports orientés code basé sur Quarto
-
Transformation déclarative des données, visualisation déclarative
- SQL est un langage spécialisé pour manipuler des données relationnelles stockées dans une ou plusieurs tables
- Sa syntaxe repose sur les concepts de l’algèbre relationnelle et offre une manière structurée de penser la manipulation des données
- La sémantique de SQL définit un ensemble d’opérations modulaires déclaratives plutôt que fonctionnelles
- La grammar of graphics est un cadre théorique qui décompose les concepts de visualisation des données en composants modulaires
- Des outils comme ggplot2 transforment ces concepts en implémentations concrètes
- La grammar of graphics définit elle aussi un ensemble d’opérations modulaires déclaratives plutôt que fonctionnelles
- Les deux systèmes ont de nombreux points communs dans leur manière d’aborder leur domaine et permettent de construire naturellement un pipeline complet et puissant, des données brutes à la visualisation finale
-
No runtime, no problem
- ggplot2 nécessite l’installation de R, et plotnine celle de Python
- À l’inverse, un outil de visualisation fondé sur un exécutable unique et ciblé présente des avantages clairs
- Il est plus facile d’intégrer un petit exécutable dans d’autres outils que de devoir embarquer R/Python ou exiger leur installation
- Son périmètre réduit facilite la limitation par sandbox de l’exécution de code malveillant ou accidentel
- Ces caractéristiques rendent ggsql plus attractif pour l’intégration dans des assistants d’analyse IA ou des outils de reporting orientés code exécutant du code dans divers environnements
- S’éloigner des langages interprétés implique aussi des contraintes, mais apporte des bénéfices importants
- L’avantage le plus important est que, grâce à sa structure stricte, le backend peut exécuter l’ensemble du pipeline de données de chaque couche dans une seule requête SQL
- Par exemple, pour tracer un diagramme en barres sur 10 milliards de transactions, seules les valeurs de count de chaque barre sont récupérées depuis le data warehouse, et non l’ensemble des 10 milliards de lignes
- Le même principe s’applique à des types de couches plus complexes comme les boxplots ou les density plots
- Cela contraste avec la plupart des outils de visualisation qui matérialisent d’abord l’ensemble des données avant de calculer et d’afficher le graphique
-
SELECT pod_door FROM bay WHERE closed- Les LLM ont démontré une grande efficacité pour convertir le langage naturel en SQL
- Il est avancé que le même niveau d’efficacité pourrait s’appliquer à ggsql
- Dans
querychat, l’exploration visuelle des données en langage naturel est déjà possible via ggsql - ggsql étant un runtime plus sûr et plus léger que R ou Python, il offre plus de garanties pour déployer des agents de codage en production
-
We are now wise beyond our years
- Les 18 années de développement et de maintenance de ggplot2 représentent 18 années de réflexion accumulée sur la grammaire de visualisation, l’utilisabilité et la conception
- Il n’est pas possible de réinjecter entièrement ce savoir dans ggplot2
- Il faut respecter des décisions anciennes et les attentes des utilisateurs, et même en les remettant en question, cela ne peut se faire que très progressivement
- ggsql est une blank slate
- Un projet construit à partir de zéro
- Un système conçu pour un environnement sans attentes préexistantes sur les outils de visualisation
- Il est indiqué que ce point de départ a apporté un sentiment de liberté et d’énergie au processus de développement, et que cela se ressent dans l’expérience utilisateur
Avenir
- La version actuelle est une alpha-release et n’est pas encore terminée
- Une liste non exhaustive des éléments prévus pour la suite est présentée
- Un nouveau writer haute performance écrit en Rust de zéro
- Une infrastructure de thèmes
- L’interactivité
- Un flux de déploiement de bout en bout de Posit Workbench ou Positron vers Connect
- Un language server ggsql complet et un formatter de code
- La prise en charge des données spatiales
-
Qu’est-ce que cela signifie pour le développement de ggplot2
- Il est mentionné que les utilisateurs de ggplot2 peuvent accueillir l’annonce de ggsql avec un mélange d’inquiétude et d’attente
- À la question de savoir si Posit délaisse ggplot2 pour se concentrer sur ggsql, la réponse est non
- ggplot2 est déjà très mature et stable, mais il est prévu de continuer à le soutenir et à l’étendre
- Il est espéré que le développement de ggsql contribuera aussi à apporter de nouvelles fonctionnalités à ggplot2
En savoir plus
- Pour commencer à utiliser ggsql immédiatement, la section Getting started du site web de ggsql propose un guide d’installation et un tutoriel
- La page de documentation permet de consulter l’ensemble des fonctionnalités prises en charge par ggsql
- Le texte précise également qu’un retour sur l’expérience utilisateur est attendu
1 commentaires
Avis Hacker News
C’est peut-être parce que j’ai parcouru l’article trop vite, mais en ne lisant que le billet de blog et la documentation, j’ai eu l’impression que la relation avec les bases de données SQL n’était pas expliquée clairement
Au début, j’ai supposé qu’il s’agissait simplement d’une sorte de DSL de visualisation proche de SQL géré par une bibliothèque de graphiques frontend
La documentation anatomy se lisait comme ça, mais dans la FAQ à la question "Can I use SQL queries inside the VISUALISE clause", il était indiqué qu’une partie de la syntaxe était transmise directement à la base de données
Sur la page d’accueil, il est écrit que "ggsql interfaces directly with your database", mais la manière dont la connexion se fait réellement ne sautait pas aux yeux, ce qui m’a laissé perplexe
ggsql peut se connecter directement à un backend de base de données et, si on le souhaite, il peut aussi s’exécuter avec DuckDB en mémoire
Les requêtes de visualisation sont converties en requêtes SQL pour chaque couche de la visualisation, puis les tables résultantes sont utilisées pour le rendu
Par exemple, une requête comme
VISUALISE page_views AS x FROM visits DRAW smoothest transformée en SQL qui calcule un noyau de lissage sur les données, puis la courbe finale est tracée à partir des points renvoyésLe reader gère la connexion à la base de données et la génération du dialecte SQL adapté à chaque SGBD
À l’étape alpha actuelle, il prend en charge duckdb, sqlite, ainsi qu’un reader ODBC expérimental, et le développement se concentre surtout sur DuckDB avec des fichiers locaux
L’idée centrale est de transformer une requête de visualisation en plusieurs requêtes SQL exécutées dans la base, puis de construire le graphique uniquement à partir de la petite quantité de résultats renvoyés
Ainsi, même avec un très grand nombre de lignes, on peut calculer en SQL seulement les statistiques nécessaires à un histogramme, puis ne récupérer que quelques points pour dessiner la hauteur des barres
La valeur par défaut est une connexion DuckDB en mémoire, et dans le CLI on peut utiliser
--readerpour se connecter à un fichier sur disque ou à un URI ODBCDans Positron, cela peut se configurer plus facilement via le volet "Connections", et dans le kernel Jupyter de ggsql, on peut spécifier le reader avec un commentaire SQL magique
Il est aussi prévu de renforcer la documentation sur cette intégration avec des outils externes
SQL est un langage déclaratif de manipulation de données ; on l’utilise souvent pour interroger des bases de données, mais il n’y est pas limité
On peut aussi appliquer SQL à des fichiers plats, des flux de données ou des données en mémoire dans un programme
Et à l’inverse, on peut tout à fait interroger une base de données sans SQL
En parcourant l’article, j’essayais de comprendre pourquoi c’était nécessaire et quel problème cela résolvait, mais cela ne m’a pas vraiment parlé
Je me suis demandé si l’idée était de visualiser directement des tables d’une base SQL distante, en évitant d’abord l’étape consistant à les rapatrier dans un data frame R avant de lancer ggplot
Mais je me demandais aussi pourquoi créer un nouveau langage de type SQL
R dispose déjà de dbplyr pour traduire entre R et SQL, donc je me suis dit qu’il serait peut-être plus direct d’étendre ggplot pour qu’il prenne en charge directement les objets tbl de dbplyr et génère du SQL
Ou alors, comme SQL est déjà un langage extrêmement familier, peut-être que l’idée est que beaucoup de gens voudront faire des choses de type ggplot avec cette syntaxe
Ce n’est qu’après avoir lu presque toute la documentation que j’ai compris qu’il s’agissait d’une application de visualisation autonome avec des backends DuckDB et SQLite, qui s’appuie actuellement sur Vegalite pour le rendu et prévoit d’ajouter d’autres backends et moteurs de rendu plus tard
Comme le dit un commentaire plus bas, cela semble être un outil destiné à permettre à des utilisateurs centrés sur SQL de créer des visualisations sans connaître Python ou R
Je suis d’accord pour dire que l’article de présentation aurait pu mieux l’expliquer
D’après mon expérience, le langage commun partagé par les analystes, les scientifiques et les ingénieurs est souvent avant tout SQL
On peut faire la même chose en R, mais dans la pratique les projets ne sont pas forcément écrits en R ou en Python, alors qu’une base SQL et un moteur d’accès existent souvent déjà
J’utilise aussi souvent des cellules SQL dans un notebook marimo avec DuckDB en arrière-plan, et pouvoir tracer directement depuis SQL y serait très pratique
Enfin, j’ai toujours trouvé que les API de visualisation Python étaient assez difficiles à mémoriser et à manier
Même pour faire un simple scatterplot avec matplotlib, il y a énormément de boilerplate, donc avoir une syntaxe unifiée dans le même langage de requête me paraît très appréciable
Le point intéressant est moins une bibliothèque particulière que la combinaison entre SQL comme interface et la formalisation GoG
Le moteur de rendu ou le runtime réels ont leur importance, mais cela relève davantage du détail d’implémentation
Bien sûr, ce n’est pas quelque chose qu’on ne pourrait pas aussi faire facilement en R ou en Python, ou avec matplotlib, avec un nombre de lignes comparable
En revanche, sandboxer ce type d’environnement de manière sûre face à des entrées malveillantes est difficile, alors qu’avec un tel langage déclaratif, il devient plus facile d’héberger un service où des utilisateurs non fiables soumettent du ggsql et n’obtiennent qu’un graphique en retour
En ce sens, cela a une vraie utilité
Cela dit, dans la plupart des usages courants, il sera peut-être plus simple de demander à son LLM préféré de générer du code matplotlib
J’encourage le projet lui-même, et je suis largement d’accord sur le fait que le concept colle très bien à SQL
En R, préparer les données avec un WITH puis ajouter un VISUALIZE ensuite ressemble déjà beaucoup à ma manière de faire pour le plotting
En dehors de l’avantage d’un DSL simple, j’ai encore du mal à voir quel serait l’avantage par rapport à ggplot2 qui justifierait le coût de créer un DSL de plus
La seule vraie raison qui me ferait presque quitter ggplot2 pour la visualisation, c’est que dès qu’on sort du cadre standard où un geom existe déjà, il devient assez difficile de faire des visualisations non standard
Quand je veux construire quelque chose d’un peu différent, il m’est souvent bien plus facile de redescendre à des primitives de dessin de bas niveau que d’essayer de bricoler un adaptateur compatible ggplot
Même encapsuler les spécifications partielles les plus courantes dans des fonctions n’est pas toujours fluide, selon que cela se compose avec
+ou s’enchaîne avec des pipes comme|>ou l’ancien%>%Et nous n’avons absolument pas l’intention d’arrêter de développer ggplot2
ggsql est en partie un projet destiné à toucher un nouveau public et à proposer des visualisations puissantes dans de nouveaux contextes
Si quelqu’un passe l’essentiel de son temps dans R, il n’est probablement pas l’utilisateur cible principal
Cela dit, il y a aussi des éléments assez intéressants que ggplot2 n’a pas, donc cela peut valoir le coup d’explorer
|>et%>%ne sont pas le même opérateurLe pipe natif plus récent
|>est plus rapide, mais il ne prend pas en charge des fonctionnalités comme le placeholder point de%>%pour passer l’argument ailleurs qu’en première positionDonc, dans certains cas,
%>%peut rendre l’expression un peu plus éléganteJe trouve ça vraiment bien
Nous sommes arrivés à des conclusions similaires en créant GFQL, un graph dataframe query language
Nous avions en particulier besoin d’une interface compatible avec les LLM pour la visualisation et la pile d’analyse, sans avoir à ouvrir l’exécution à du code arbitraire
Nous avons vérifié qu’avec de simples extensions d’opencypher, on pouvait déjà construire un pipeline d’analyse visuelle GPU très riche, et pour la même raison, l’approche consistant à aller vers SQL dans le monde tabulaire me semble tout à fait pertinente
Pour des exemples côté GFQL, on peut jeter un œil à overall pipelines qui couvre le chargement de données, les transformations de forme, l’enrichissement par algorithmes, l’encodage visuel et les pipelines de première classe, ainsi qu’à declarative visual encodings sous une forme d’appels plus simple
Ça a l’air assez prometteur
J’aimerais toutefois qu’il existe un moyen de degrader avec élégance dans des environnements où la syntaxe n’est pas prise en charge
J’avais déjà imaginé une approche comparable, à l’intérieur même de SQL mais beaucoup plus simple que GoG, et dans ce cas une dégradation restait possible
La syntaxe n’était pas très agréable à lire, mais c’était dans l’esprit de la spec sqlnb
Si possible, j’aimerais une explication un peu plus concrète
Parmi les outils dans la même veine, Shaper me vient aussi à l’esprit, basé sur DuckDB
L’approche consiste à piloter tout un dashboard en mode SQL-first, et la documentation getting started donne une impression de direction assez proche
D’abord, ggsql a vraiment l’air formidable et j’ai hâte de l’essayer
Mais il y avait un point visiblement absent de la documentation : j’ai eu du mal à trouver une explication sur les formats de sortie
Je ne voyais pas clairement si on pouvait produire du PDF, si SVG ou PNG étaient pris en charge, ni comment contrôler la taille en largeur et hauteur
L’indice le plus proche que j’ai trouvé était
chart.display()etchart.save("chart.html")dans la documentation de la bibliothèque PythonCette sortie peut déjà être rendue en graphique interactif, SVG, PNG, etc., avec des outils existants, et pour le contrôle de la taille il faut suivre les réglages de ces outils
Le kernel Jupyter de ggsql peut utiliser cette spec vegalite pour afficher des graphiques dans des documents Quarto
À l’avenir, il est prévu de créer un writer haute performance qui ne passera pas par cette étape intermédiaire vegalite ; à ce moment-là, il sera sans doute possible de répondre plus clairement à ce genre de questions
Je me demandais s’il existait des plans d’intégration avec les packages d’extension ggplot2, dans un futur proche ou lointain
Désolé si cela avait déjà été mentionné
Le but de ce projet n’est pas de remplacer ggplot2, mais de proposer une autre approche
Il pourra faire beaucoup de choses que fait ggplot2, et peut-être certaines que ggplot2 ne fait pas, mais pendant encore longtemps ggplot2 restera probablement plus puissant pour de nombreux usages
Ça a l’air vraiment excellent, et je pense l’essayer bientôt
Ce qui m’a vraiment parlé, c’est l’explication dans la documentation grammar
Le fait de sélectionner d’abord les données avec un SELECT déjà familier, de passer ensuite de la table au graphique avec
VISUALIZEouVISUALISE, puis de mapper les aesthetics avecDRAW, avant d’empilerSCALE,FACETetLABEL, prolonge de façon très naturelle la manière structurée de penser propre à SQLJ’aime vraiment beaucoup l’approche par couches
Dès qu’on commence à dépasser le graphique de base, cette méthode semble très bien résoudre les problèmes que j’ai souvent rencontrés avec d’autres outils hybrides SQL/visualisation