11 puntos por GN⁺ 9 일 전 | 1 comentarios | Compartir por WhatsApp
  • Herramienta de visualización basada en sintaxis SQL que combina en un mismo flujo la consulta de datos y la construcción de gráficos mediante cláusulas como VISUALIZE, DRAW, PLACE, SCALE y LABEL
  • Permite mapear columnas a propiedades visuales y, con un enfoque de composición por capas, construir dentro de una misma estructura diagramas de dispersión, gráficos de barras, histogramas, boxplots e incluso elementos de anotación
  • Los resultados de consultas SQL se pasan directamente como entrada de visualización, y algunas capas tienen una estructura que obtiene solo las agregaciones mediante la ejecución de una sola consulta SQL, lo que resulta ventajoso para procesar grandes volúmenes de datos
  • Diseñado con la idea de un ejecutable pequeño y enfocado que puede usarse sin runtime de R o Python, lo que también resalta su idoneidad para integrarse en herramientas de reportes basadas en código y asistentes de análisis con IA
  • La versión actual es una alpha-release, y se presentan planes de expansión como writer de alto rendimiento, temas, interactividad, language server, formatter y soporte para datos espaciales

Introducción a ggsql

  • ggsql es una implementación de grammar of graphics basada en sintaxis SQL que añade capacidades de visualización estructuradas a SQL
    • Puede usarse en Quarto, Jupyter notebooks, Positron, VS Code y más
  • Está diseñado para que los usuarios de SQL puedan escribir código de visualización de una forma familiar
    • Aplica a la gramática de visualización la estructura declarativa y componible de cláusulas propia de SQL
  • Presenta la motivación y ejemplos de uso, desarrollando la sintaxis central de ggsql

Ejemplos básicos

  • Primer gráfico

    • Se puede crear un diagrama de dispersión con el dataset integrado penguins
      • VISUALIZE bill_len AS x, bill_dep AS y FROM ggsql:penguins
      • DRAW point
    • En VISUALIZE, las columnas de datos se mapean a propiedades visuales, y DRAW point crea una capa de puntos usando ese mapeo base
    • Con solo añadir species AS color, se puede aplicar una distinción por categorías de color
      • VISUALIZE bill_len AS x, bill_dep AS y, species AS color FROM ggsql:penguins
      • DRAW point
    • Al añadir DRAW smooth, se puede apilar una capa de línea de regresión sobre la capa de puntos
      • Se mantiene el mapeo de color por especie, por lo que se genera una línea separada para cada species
    • En lugar de adoptar tipos de gráficos predefinidos, usa un enfoque de combinación de componentes modulares
    • Manteniendo la misma estructura, es posible cambiar a una visualización completamente distinta
      • VISUALIZE island AS x, species AS color FROM ggsql:penguins
      • DRAW bar
  • Ejemplo completo

    • La parte superior se distingue como una consulta SQL común, y después de VISUALIZE comienza la consulta de visualización
      • En el ejemplo se usa un backend de DuckDB
    • La parte SQL usa ROW_NUMBER() y QUALIFY para conservar solo la misión más reciente por nombre a partir de astronauts.parquet
    • Luego se combinan dos conjuntos
      • Se calcula year_of_selection - year_of_birth como age y se asigna la categoría Age at selection
      • Se calcula year_of_mission - year_of_birth como age y se asigna la categoría Age at mission
      • Ambos resultados se combinan con UNION ALL
    • En la consulta de visualización se mapean age AS x y category AS fill, y luego se usa DRAW histogram
      • Se especifica SETTING binwidth => 1, position => 'identity'
    • PLACE rule añade una anotación en la posición media calculada previamente
      • x => (34, 44), linetype => 'dotted'
    • PLACE text añade anotaciones de texto
      • x => (34, 44, 60)
      • y => (66, 49, 20)
      • La etiqueta incluye 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!
      • Se especifican hjust => 'left', vjust => 'top', offset => (10, 0)
    • SCALE fill TO accent convierte los valores mapeados de fill a la paleta de color accent
    • La cláusula LABEL controla el título, subtítulo, etiqueta del eje x y la etiqueta de la leyenda
      • Título: How old are astronauts on their most recent mission?
      • Subtítulo: Age of astronauts when they were selected and when they were sent on their mission
      • Eje x: Age of astronaut (years)
      • fill => null

Estructura de la consulta de visualización

  • Antes de VISUALIZE hay SQL puro, y la tabla resultante no se devuelve como tabla, sino que se pasa directamente como entrada a la visualización
  • Las tablas o CTE creadas en la parte SQL pueden referenciarse en la consulta de visualización
  • Si los datos ya están en una forma adecuada para visualizarse, la parte SQL puede omitirse
    • VISUALIZE year_of_selection AS x, year_of_mission AS y FROM 'astronauts.parquet'
  • VISUALIZE o VISUALISE marca el final de la consulta SQL y el comienzo de la consulta de visualización
  • El mapeo cumple la función de conectar columnas con propiedades visuales, es decir, aesthetics
    • En el ejemplo, age corresponde a la posición en el eje x y category al color de relleno
  • DRAW añade capas a la visualización
    • Hay tipos simples como point y otros como histogram, que requieren calcular agregaciones por intervalos
    • Las capas se renderizan en el orden en que se definen
  • PLACE es una cláusula hermana de DRAW dedicada exclusivamente a annotation, usando valores literales en lugar de datos tabulares
    • La visualización del ejemplo consta de tres capas: una capa de histograma, una capa de anotación de línea guía y una capa de anotación de texto
    • Una capa no necesariamente corresponde a un único objeto gráfico, y puede renderizar varios objetos individuales del mismo tipo
  • SCALE es la cláusula que transforma valores de datos en valores adecuados para un aesthetic
    • Además de convertir categorías de texto en colores reales, también puede realizar transformaciones continuas, definir break points y establecer tipos de escala como ordinal o binned
  • LABEL permite añadir y modificar etiquetas de texto como título, subtítulo, títulos de ejes y títulos de leyenda

Dando un paso atrás

  • El ejemplo anterior incluye mucha sintaxis, pero cubre de una vez partes importantes del núcleo del lenguaje
  • Muchas consultas de visualización pueden ser mucho más simples que eso
  • Se presenta un ejemplo de boxplot del año de nacimiento por género usando astronauts.parquet
    • VISUALIZE sex AS x, year_of_birth AS y FROM 'astronauts.parquet'
    • DRAW boxplot
  • El código puede ser más largo que en otros sistemas de gráficos, pero ofrece propiedades más estructuradas, componibles y autoexplicativas
  • Estas propiedades facilitan que los usuarios interioricen el comportamiento de todo tipo de gráficos, y también benefician a futuros asistentes de codificación basados en LLM
  • La misma relación puede convertirse fácilmente en un diagrama de dispersión con jitter
    • DRAW point
    • SETTING position => 'jitter'
  • También se puede hacer que el jitter siga la distribución de los datos para darle carácter de violin plot
    • SETTING position => 'jitter', distribution => 'density'
  • Esta estructura sintáctica y capacidad de composición facilitan el trabajo repetitivo en el análisis exploratorio y el diseño de visualizaciones

¿Por qué ggsql?

  • Se presentan cinco razones para desarrollar ggsql
    • Apoyar a analistas y científicos de datos que trabajan principalmente con SQL
    • La alta afinidad entre SQL y grammar of graphics
    • Construir una herramienta potente de visualización basada en código sin depender de un lenguaje de programación completo como R o Python
    • Las grandes capacidades de los LLM para procesar SQL y las nuevas posibilidades de interfaces de visualización
    • Aplicar 18 años de experiencia desarrollando ggplot2 sobre una nueva base
  • Hello, SQL user

    • Aunque durante la revolución de la ciencia de datos R y Python recibieron gran atención, SQL ha seguido siendo una base confiable para trabajar con datos
    • Existe una gran cantidad de personas que trabajan con datos usando solo SQL o principalmente SQL
    • Para ellas, las opciones de visualización existentes mencionadas en el texto son en general poco óptimas
      • Exportar los datos para usar R o Python
      • Usar herramientas BI basadas en GUI con escaso soporte para reproducibilidad
      • Usar herramientas de visualización integradas en la propia consulta, pero consideradas insuficientemente potentes o ergonómicas
    • La sintaxis de ggsql está diseñada para que los usuarios de SQL la entiendan de inmediato
      • Aprovecha la expectativa de cláusulas declarativas y componibles
    • ggsql no solo mejora la forma de visualizar, sino que también sirve para incorporar a los usuarios de SQL al ecosistema de creación y compartición de reportes basados en código con Quarto
  • Transformación declarativa de datos, visualización declarativa

    • SQL es un lenguaje específico de dominio para tratar datos relacionales almacenados en una o más tablas
    • La sintaxis de SQL se basa en conceptos de álgebra relacional y ofrece una forma de pensar estructuralmente la manipulación de datos
    • La semántica de SQL no es funcional, sino que define un conjunto declarativo de operaciones modulares
    • La grammar of graphics es un marco teórico que descompone el concepto de visualización de datos en componentes modulares
    • Herramientas como ggplot2 llevan ese concepto a una implementación práctica
    • La grammar of graphics también define un conjunto declarativo de operaciones modulares más que funcionales
    • Ambos sistemas comparten mucho en la forma en que abordan sus respectivos dominios, y permiten construir un pipeline integral natural y potente desde los datos en bruto hasta la visualización final
  • No runtime, no problem

    • ggplot2 requiere una instalación de R, y plotnine requiere una instalación de Python
    • En cambio, una herramienta de visualización basada en un ejecutable único y enfocado tiene ventajas claras
      • Es más fácil integrar un ejecutable pequeño dentro de otras herramientas que empaquetar R/Python o exigir su instalación
      • Al tener un alcance reducido, es más sencillo limitar con sandbox la ejecución de código malicioso o accidental
    • Estas características hacen de ggsql una opción más atractiva para integrarse en asistentes de análisis con IA o herramientas de reportes basadas en código que ejecutan código en múltiples entornos
    • Salirse de un lenguaje interpretado también implica limitaciones, pero hay mucho que se gana
    • La ventaja más importante es que, gracias a su estructura estricta, el backend puede ejecutar por capa todo el pipeline de datos como una única consulta SQL
      • Por ejemplo, al crear un bar plot con 10 mil millones de transacciones, desde el data warehouse solo se obtienen los valores de conteo de cada barra, sin traer las 10 mil millones de filas completas
      • El mismo principio se aplica a tipos de capas más complejos como boxplot o density plot
    • Esta es una característica que contrasta con la mayoría de las herramientas de visualización, que primero materializan todos los datos y luego calculan y grafican
  • SELECT pod_door FROM bay WHERE closed

    • Está demostrado que los LLM son muy eficaces para convertir lenguaje natural en SQL
    • Se plantea la expectativa de que el mismo nivel de eficacia pueda aplicarse a ggsql
    • En querychat, ya es posible la exploración visual de datos en lenguaje natural mediante ggsql
    • Como ggsql tiene un runtime más seguro y ligero que R o Python, ofrece mayor confianza al desplegar agentes de código en entornos de producción
  • We are now wise beyond our years

    • Los 18 años de desarrollo y mantenimiento de ggplot2 representan 18 años de reflexión acumulada sobre gramáticas de visualización, usabilidad y diseño
    • No todo ese conocimiento puede volver a incorporarse a ggplot2
      • Hay que respetar decisiones tomadas hace mucho tiempo y las expectativas de los usuarios, y aun cuando se desafían, solo puede hacerse de forma muy gradual
    • ggsql es una blank slate
      • Un proyecto construido desde cero
      • Un sistema diseñado para entornos sin expectativas previas sobre herramientas de visualización
    • Se afirma que ese punto de partida dio una sensación de libertad y energía durante el desarrollo, y que eso también se refleja en la experiencia del usuario

Futuro

  • La versión actual es una alpha-release y todavía no está terminada
  • Se presenta una lista no exhaustiva de lo que se quiere añadir en adelante
    • Un nuevo writer de alto rendimiento escrito desde cero en Rust
    • Infraestructura de temas
    • Interactividad
    • Flujo de despliegue de extremo a extremo desde Posit Workbench o Positron hasta Connect
    • Un language server completo de ggsql y formatter de código
    • Soporte para datos espaciales
  • ¿Qué significa para el desarrollo de ggplot2?

    • Se menciona que los usuarios de ggplot2 podrían ver el anuncio de ggsql con una mezcla de temor y expectativa
    • A la pregunta de si Posit dejará de lado ggplot2 para concentrarse en ggsql, la respuesta es no
    • ggplot2 ya es muy maduro y estable, pero se planea seguir dándole soporte y expandiéndolo
    • Se espera que el proceso de desarrollo de ggsql también contribuya a aportar nuevas funcionalidades a ggplot2

Más información

  • Si quieres empezar a usar ggsql de inmediato, en la sección Getting started del sitio web de ggsql puedes consultar la guía de instalación y el tutorial
  • En la página de documentación puedes ver todas las funcionalidades que soporta ggsql
  • También se menciona que esperan recibir comentarios sobre la experiencia de uso

1 comentarios

 
GN⁺ 9 일 전
Comentarios en Hacker News
  • Puede que haya sido porque le di una lectura rápida al texto, pero solo con la entrada del blog y la documentación sentí que la relación con las bases de datos SQL no quedaba explicada con claridad
    Al principio supuse que era algo así como una DSL de visualización parecida a SQL que procesaba una librería de gráficos frontend
    El documento de anatomy se leía de esa forma, pero en el FAQ de "Can I use SQL queries inside the VISUALISE clause" decía que parte de la sintaxis se envía directamente a la base de datos
    En la página principal dice "ggsql interfaces directly with your database", pero no quedaba claro cómo se conecta realmente, y eso me confundió

    • Me parece una observación válida. El concepto en sí tiene una estructura un poco inusual
      ggsql puede conectarse directamente al backend de base de datos y, si se quiere, también puede ejecutarse sobre DuckDB en memoria
      Las consultas de visualización se convierten en consultas SQL para cada capa de la visualización, y luego esas tablas resultantes se usan para renderizar
      Por ejemplo, una consulta como VISUALISE page_views AS x FROM visits DRAW smooth se transforma en SQL que calcula un kernel de smoothing sobre los datos, y con los puntos devueltos se dibuja el gráfico de líneas final
    • En ggsql existe el concepto de reader, y eso cumple el papel de interfaz de conexión con una base de datos SQL
      El reader se encarga de la conexión a la base de datos y de generar el dialecto SQL adecuado para cada DB
      En esta etapa alpha, por ahora soporta duckdb, sqlite y un reader ODBC experimental, y el desarrollo se está haciendo principalmente en torno a DuckDB local basado en archivos
      La idea central es convertir una consulta de visualización en varias consultas SQL, ejecutarlas en la base de datos y construir el gráfico solo con la pequeña cantidad de resultados que regresan
      Así, incluso si hay muchísimas filas, puede calcular en SQL solo las estadísticas necesarias para un histograma y traer únicamente unos pocos puntos necesarios para dibujar la altura de las barras
      El valor predeterminado es una conexión DuckDB en memoria, y en el CLI se puede conectar a un archivo en disco o a un URI ODBC con --reader
      En Positron se puede configurar más fácilmente desde el panel de "Connections", y en el kernel de Jupyter de ggsql se puede especificar el reader con un magic SQL comment
      También planean reforzar en la documentación la explicación de este tipo de integración con herramientas externas
    • Yo también tenía la misma duda. Si hubiera un ejemplo que mostrara todo el flujo de cableado y dependencias para crear gráficos desde un servidor de base de datos externo, sería mucho más fácil de entender
    • Para mí, SQL y una base de datos no son el mismo concepto
      SQL es un lenguaje declarativo de manipulación de datos; se usa con frecuencia para consultar bases de datos, pero no está atado exclusivamente a ellas
      SQL también puede aplicarse a archivos planos, flujos de datos o datos en la memoria de un programa
      Y a la inversa, también es posible consultar una base de datos sin usar SQL
  • Mientras iba leyendo el texto, trataba de encontrar por qué esto era necesario y qué problema resolvía, pero no terminé de captarlo
    Pensé que quizá buscaba visualizar directamente tablas de una base de datos SQL remota y evitar el paso de traerlas primero a un data frame de R para luego correr ggplot
    Pero entonces también me pregunté por qué había que crear un nuevo lenguaje tipo SQL
    En R ya existe dbplyr, que traduce entre R y SQL, así que me parecía más directo extender ggplot para que soportara objetos tbl de dbplyr y generara SQL directamente
    O quizá la idea es que SQL ya es un lenguaje tan familiar que mucha gente querría hacer tareas estilo ggplot con esta sintaxis
    Recién después de leer casi toda la documentación entendí que esto es una app de visualización independiente con backends DuckDB y SQLite, que hoy renderiza con Vegalite y que más adelante planea sumar más backends y renderers
    Como dice un comentario más abajo, parece una herramienta para que usuarios centrados en SQL puedan crear visualizaciones sin saber Python ni R

    • A mí esta presentación me pareció bastante interesante, así que creo que puedo explicar por qué me resulta atractiva desde mi punto de vista
      Claro, coincido en que habría sido mejor si la presentación lo hubiera explicado un poco más claramente
      En mi experiencia, el lenguaje común que comparten analistas, científicos e ingenieros muchas veces termina siendo SQL
      En R también se puede hacer lo mismo, pero en los proyectos reales no siempre se trabaja en R o Python; en cambio, casi siempre ya existen una base de datos SQL y un motor de acceso
      Además, yo uso con frecuencia celdas SQL en marimo notebook con DuckDB en segundo plano, y ahí sería muy cómodo poder graficar directamente en SQL
      Por último, siempre me ha parecido que las API de gráficos en Python son difíciles de memorizar y dominar
      Incluso para dibujar un scatterplot simple con matplotlib hay demasiado boilerplate, así que tener una sintaxis unificada dentro del mismo lenguaje de consultas me parece bastante atractivo
    • Yo no lo veo como algo sobre ggplot en sí, sino como un intento de combinar una sintaxis tipo SQL con la Grammar of Graphics
      Lo interesante está en la combinación de SQL como interfaz con la formalidad de GoG, más que en una librería específica
      El renderer o el runtime importan, claro, pero me parecen más bien detalles de implementación
    • A mí me pareció una herramienta para usuarios de SQL que no conocen Python ni R
    • Sí le veo una ventaja clara a que sea un lenguaje declarativo para crear gráficos directamente desde SQL
      Por supuesto, no es algo imposible de hacer con una cantidad parecida de código en R o Python con matplotlib
      Pero hacer sandboxing de esos entornos de forma segura ante entradas maliciosas es difícil, y con un lenguaje declarativo como este sería más fácil alojar un servicio donde usuarios no confiables ingresen ggsql y solo se genere el gráfico
      En ese sentido sí tiene utilidad
      Aunque para la mayoría de los usos comunes, quizá sea más fácil pedirle a tu LLM favorito que te genere código de matplotlib
  • Apoyo el proyecto en sí, y coincido bastante en que el concepto encaja muy bien con SQL
    En R, preparar datos con WITH y luego agregar VISUALIZE se parece bastante a cómo ya escribo mi código de gráficos
    Pero más allá de la ventaja de ser una DSL simple, todavía no tengo claro cuál sería la ventaja frente a ggplot2 que justifique el costo de crear otra DSL
    Casi la única razón por la que dejaría ggplot2 por temas de visualización es que, en cuanto uno se sale de los casos estándar donde ya existe un geom, se vuelve bastante difícil hacer visualizaciones no estándar
    Cuando quiero construir algo un poco distinto, muchas veces me resulta mucho más fácil bajar a drawing primitives de nivel inferior que tratar de forzar un adaptador amigable con ggplot
    Incluso envolver especificaciones parciales comunes dentro de funciones no siempre se siente fluido, según si se componen con + o si se encadenan con pipes como |> o el viejo %>%

    • Nuestro objetivo no es hacer que nadie abandone ggplot2
      Y tampoco tenemos ningún plan de dejar de desarrollar ggplot2
      ggsql es, en parte, un proyecto para llegar a nuevos tipos de usuarios y llevar visualizaciones potentes a nuevos contextos
      Si alguien pasa la mayor parte de su tiempo en R, probablemente no sea el usuario objetivo principal
      Aun así, sí hay algunos elementos bastante interesantes que no están en ggplot2, así que puede ser entretenido explorarlo
    • Como comentario aparte, |> y %>% no son el mismo operador
      El pipe base relativamente reciente, |>, es más rápido, pero no admite funciones como el placeholder con punto de %>% para pasar argumentos a posiciones distintas de la primera
      Por eso, en algunos casos, %>% puede hacer que una expresión quede un poco más limpia
  • Esto me parece realmente bueno
    Nosotros también llegamos a conclusiones parecidas al crear GFQL, un graph dataframe query language
    En particular, necesitábamos una interfaz amigable para LLM que pudiera usarse en stacks de visualización y análisis sin sandbox de código
    Confirmamos que incluso con extensiones básicas de opencypher se puede construir un pipeline bastante rico de análisis visual sobre GPU, y por la misma razón el enfoque de ir hacia SQL en el mundo tabular también me parece totalmente razonable
    Como ejemplos del lado de GFQL, vale la pena revisar overall pipelines, que cubre carga de datos, transformación de shape, enrichment basado en algoritmos, visual encoding y pipelines de primera clase, así como declarative visual encodings, con un estilo de llamada más simple

  • Esto se ve bastante bien
    Pero me gustaría que hubiera una forma de que degradara con elegancia incluso en entornos sin soporte para esa sintaxis
    Yo también ideé un enfoque parecido, aunque mucho más simple que GoG, para usar dentro de SQL, y ese sí podía degradarse
    No era una sintaxis muy agradable de leer, pero era algo como la spec de sqlnb

    • Yo me confundí un poco con qué significa exactamente "degrade in context"
      Si es posible, estaría bien que lo explicaras un poco más en concreto
  • Otra herramienta en una línea parecida que me viene a la mente es Shaper, basado en DuckDB
    Su enfoque también es manejar dashboards completos con una lógica SQL-first, y al ver la documentación de getting started me dio la impresión de que va por un rumbo similar

  • Antes que nada, ggsql se ve realmente genial y tengo ganas de probarlo pronto
    Pero sí noté algo que parecía faltar en la documentación: costaba encontrar una explicación de los formatos de salida
    No quedaba claro si puede exportar a PDF, si soporta SVG o PNG, o cómo se controlan cosas como el tamaño horizontal y vertical de salida
    La pista más cercana que encontré fue chart.display() y chart.save("chart.html") en la documentación de la librería de Python

    • Actualmente el módulo writer es exclusivo para vegalite, y la salida es JSON en formato vegalite spec
      Esa salida ya puede renderizarse como gráfico interactivo, SVG, PNG y demás con herramientas existentes, y controles como el tamaño se manejan siguiendo la configuración de esas herramientas
      El kernel de Jupyter de ggsql puede usar este vegalite spec para mostrar gráficos dentro de documentos Quarto
      Más adelante planean crear un writer de alto rendimiento que no pase por esta etapa intermedia de vegalite, así que en ese momento probablemente puedan dar una respuesta más clara a este tipo de preguntas
  • Me preguntaba si hay planes de integración con los paquetes de extensión de ggplot2 en el futuro cercano o lejano
    Si ya lo mencionaron antes, disculpas

    • Creo que será difícil incorporar en el corto plazo varios de los geom de nicho creados por la comunidad de ggplot2
      El objetivo de este proyecto no es reemplazar ggplot2, sino ofrecer un enfoque distinto
      Puede hacer muchas de las cosas que hace ggplot2, e incluso algunas que ggplot2 no puede, pero creo que durante mucho tiempo ggplot2 seguirá siendo más potente para muchas tareas
  • Esto se ve realmente genial y pienso probarlo pronto
    Lo que más me hizo clic fue la explicación en el documento de grammar
    Me impresionó cómo el flujo conserva exactamente la forma estructurada de pensar de SQL: eliges datos con el ya familiar SELECT, cambias de tabla a gráfico con VISUALIZE o VISUALISE, luego mapeas aesthetics con DRAW, y después vas apilando SCALE, FACET y LABEL

  • A mí me encantó de verdad el enfoque por capas
    Me dio la impresión de que resuelve muy bien problemas que suelen aparecer en otras herramientas híbridas de visualización en SQL cuando uno empieza a ir más allá de los gráficos básicos