6  Gráficos

6.1 Paquetes gráficos

Existen muchos paquetes para la representación gráfica en Julia. Los más usados son:

6.2 Gráficos con el paquete Plots.jl

Plots.js es el paquete más usado por disponer de más posibilidades gráficas y ser bastante sencillo de usar.

Implementa una interfaz para otras librerías gráficas (backends), por lo que en algunas ocasiones puede ser bastante lento al tener que llamar a otras librerías.

6.2.1 Backends de Plot.jl

  • GR. Es el backend pro defecto. Es bastante rápida y permite tanto gráficos 2D como 3D no interactivos. Se inicializa con la función gr(). (Ver ejemplos)
  • PlotlyJS. Es más lenta pero permite gráficos 2D y 3D interactivos con un montón de funcionalidades. Se inicializa con la función plotlyjs(). (Ver ejemplos)
  • PyPlot. Utiliza la librería gráfica Matplotlib de Python por lo que es bastante lenta. Sin embargo, tiene ofrece todas las posibilidades de Matplotlib que es bastante madura. Se inicializa con la función pyplot(). (Ver ejemplos)
  • PGFPlotsX. Utiliza la librería PGF/TikZ de LaTeX por lo que genera gráficos de muy alta calidad tanto en 2D como 3D, especialmente para publicaciones.Se inicializa con la función pgfplotsx(). (Ver ejemplos)
  • UnicodePlots. Permite dibujar gráficos en la terminal. Los gráficos son de poca calidad pero funciona con gran rapidez. Se inicializa con la función unicodeplots(). (Ver ejemplos)

6.2.2 Gráfica de una función de una variable

  • plot(f, min, max): Dibuja la gráfica de la función de una variable f para argumentos desde xmin a xmax.
using Plots

f(x) = exp(-x^2 / 2)
plot(f, -3, 3)

6.2.3 Gráficas de varias funciones

  • plot!(f, xmin, xmax): Añade la gráfica de la función de una variable f para argumentos desde xmin a xmax al último gráfico realizado.
using Plots

f(x) = sin(x)
g(x) = cos(x)
plot(f, -0, 2π)
plot!(g)

6.2.4 Añadir puntos a una gráfica

  • scatter(x, y): Dibuja los puntos con coordenadas x en el vector x y coordenadas y en el vector y.
using Plots

f(x) = sin(x)
g(x) = cos(x)
plot(f, -0, 2π)
plot!(g)
x = [π/4, 5π/4]
y = sin.(x)
scatter!(x, y)

6.2.5 Ventana de graficación

Es posible restringir el área de graficación (rango de valores de los ejes) de una función añadiendo los parámetros xlims =(xmin, xmax) para establecer el rango del eje x o ylims = (ymin, ymax) para establecer el rango del eje y.

using Plots

f(x) = 1 / x
plot(f, -1, 1, ylims = (-10, 10))

6.2.6 Restringir la gráfica al dominio

Cuando una función no está definida para algún valor del rango de valores del eje x dado, la gráfica muestra una línea recta desde el punto de la gráfica anterior hasta el punto siguiente al punto donde la función no existe.

Este comportamiento no es deseable puesto que si la función no existe en un punto no debería existir gráfica para ese punto.

La siguiente función del paquete MTH229 se encarga de evitar esto.

  • rangeclamp(f): Devuelve una función idéntica a la función f excepto para los puntos donde la función no existe o es infinito que devuelve NaN.

6.2.7 Ejemplo de restringir la gráfica al dominio

using Plots
using MTH229

f(x) = 1 / x
plot(rangeclamp(f), -1, 1)

6.2.8 Gráficas paramétricas

La función plot también permite dibujar gráficas de funciones paramétricas pasándole las funciones de las coordenadas x e y.

  • plot(f, g, min, max): Dibuja la gráfica de la función paramétrica \((f(t), g(t))\) para valores del parámetro t entre min y max.
using Plots
f(x) = sin(x)
g(x) = sin(2x)
plot(f, g, 0, 2π)

6.2.9 Personalización de gráficos

Los siguientes parámetros pueden añadirse a la función plot para modificar el aspecto de los gráficos.

  • title: Añade un título principal al gráfico.
  • xlab: Añade un título al eje x.
  • ylab: Añade un título al eje y.
  • color: Establece el color de la gráfica.
  • linewidth: Establece el grosor de la línea de la gráfica.
  • linestyle: Establece el estilo de la línea de la gráfica.
  • aspect_ratio: Establece la relación de aspecto entre la escala de los ejes.
  • legend: Activa o desactiva la leyenda del gráfico.

6.2.10 Ejemplo de personalización de gráficos

using Plots

f(x) = sin(x)
plot(f, -π, π, title = "Gráfica del seno",  xlab = "x", ylab = "f(x) = sen(x)",
  color = "green", linewidth = 3, linestyle = :dash, legend = false)

6.2.11 Gráficos en el espacio real

Para dibujar superficies en el espacio real se utiliza la función

surface(x, y, f): Dibuja la superficie de la función \(f(x,y)\) en el rango de valores x del eje x e y del eje y.

using Plots
xs = ys = range(1, stop=10, length=100)
f(x, y) = sin(x) + cos(y)
surface(xs, ys, f)

6.3 Gráficos con Makie

Makie es una colección de paquetes de visualización de datos eficiente y extensible que incorpora una gran variedad de tipos de gráficos tanto en 2D como en 3D.

6.3.1 Backends de Makie

Al igual que el paquete Plots, Makie utiliza distintos backends para construir el gráfico según la salida que se quiera.

  • CairoMakie.jl se utiliza para crear gráficos no interactivos de alta calidad, especialmente para publicaciones impresas.
  • GLMakie.jl se utiliza para crear gráficos interactivos tanto en 2D como en 3D en una ventana gráfica.
  • WGLMakie.jl es similar a GLMakie.jl pero muestra el gráfico en un navegador web.

6.3.2 Figuras, ejes y objetos gráficos

Un gráfico con Makie es básicamente una figura (Figure) que contiene uno o varios ejes (Axis) que, a su vez, contienen objetos gráficos como puntos o lineas.

Para crear una figura se utiliza la función

  • Figure(parámetros): Crea un área gráfica con la configuración indicada por los parámetros. Entre los parámetros se puede indicar la resolución (resolution = (ancho, largo)) o el color de fondo (backgroundcolor = color).
using GLMakie
fig = Figure(backgroundcolor = :gray, resolution = (400, 300))

Para añadir unos ejes en 2D a una figura se utiliza la función

  • Axis(fig[i,j], title = titulo, xlabel = etiqueta-x, ylabel = etiqueta-y): Crea unos ejes en la figura fig con el título principal dado en titulo, la etiqueta del eje \(x\) dada en etiqueta-x y la etiqueta del eje \(y\) dada en etiqueta-y.
    Cuando se quiere incluir varios ejes en una misma figura, el vector [i,j], indica la posición de los ejes, donde la primera componente indica la fila y la segunda la columna en una disposición de los ejes en forma de tabla. Si la figura solo contiene unos ejes, se utiliza el vector [1,1].
fig = Figure()
ax = Axis(fig[1,1], title = "Ejes 2D", xlabel = "Eje x", ylabel = "Eje y")
fig

Y para añadir unos ejes en 3D a una figura se utiliza la función

  • Axis3(fig[i,j], title = titulo, xlabel = etiqueta-x, ylabel = etiqueta-y, zlabel = etiqueta-z, azimuth = ángulo-azimuth, elevation = ángulo-elevación): Crea unos ejes 3D en la figura fig con el título principal dado en titulo, la etiqueta del eje \(x\) dada en etiqueta-x, la etiqueta del eje \(y\) dada en etiqueta-y, la etiqueta del eje \(z\) dada en etiqueta-z, y un punto de visión dado por el ángulo de azimuth (izquierda-derecha) angulo-azimuth radianes (\(1.275 \pi\) por defecto) y el ángulo de elevación (arriba-abajo) ángulo-elevación radianes (\(\pi/8\) por defecto). Al igual que antes, cuando se quiere incluir varios ejes en una misma figura, el vector [i,j], indica la posición de los ejes, donde la primera componente indica la fila y la segunda la columna en una disposición de los ejes en forma de tabla. Si la figura solo contiene unos ejes, se utiliza el vector [1,1].
fig = Figure()
ax = Axis3(fig[1,1], title = "Ejes 3D", xlabel = "Eje x", ylabel = "Eje y", zlabel = "Eje z")
fig

fig = Figure()
ax = Axis3(fig[1,1], title = "Ejes 3D rotados", xlabel = "Eje x", ylabel = "Eje y", zlabel = "Eje z", azimuth = pi/8)
fig

6.3.3 Diagrama de puntos

Para dibujar un diagrama de puntos se utiliza la función

  • scatter!(ax, xs, ys): Dibuja los ejes dados en ax los puntos con coordenadas dadas por los vectores xs e ys.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de puntos")
xs = [1, 2, 3]
ys = [2, 3, 1]
Makie.scatter!(ax, xs, ys)
fig

Los siguientes parámetros pueden añadirse a la función anterior para modificar el aspecto del diagrama de puntos.

  • marker: Establece el tipo de punto.
  • color: Establece el color de los puntos.
  • markersize: Establece el tamaño de los puntos.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de puntos")
xs = [1, 2, 3]
ys = [2, 3, 1]
Makie.scatter!(ax, xs, ys, marker = :utriangle, color= :red, markersize = 20)
fig

6.3.4 Diagrama de líneas

Para dibujar series de líneas se utiliza la función

  • lines!(ax, xs, ys): Dibuja en los ejes dados por ax una línea en el plano que une los puntos con coordenadas dadas por los vectores xs e ys.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
xs = range(0, 2pi, length = 100)
ys = sin.(xs)
lines!(ax, xs, ys)
fig

Si se añade un tercer vector de coordenadas zs sobre unos ejes 3D, se obtiene un diagrama de líneas en 3D. De esta forma se pueden representar, por ejemplo, la trayectorias de funciones vectoriales.

fig = Figure()
ax = Axis3(fig[1, 1], title = "Diagrama de líneas 3D")
ts = range(0, 6pi, length = 200)
xs = cos.(ts)
ys = sin.(ts)
zs = ts/4
lines!(ax, xs, ys, zs)
fig

En lugar de pasar las coordenadas de los puntos en vectores separados, se pueden pasar empaquetadas en tuplas mediante las estructuras Point(x,y) para el plano real o Point3(x,y,z) para el espacio real, del paquete GeometryBasics.jl.

fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de lineas")
ts = range(0, 2pi, length = 200)
points = Point.(cos.(ts), sin.(2ts))
lines!(ax, points)
fig

fig = Figure()
ax = Axis3(fig[1, 1], title = "Diagrama de líneas 3D")
ts = range(0, 6pi, length = 200)
f(t) = [cos(t), sin(t), t/4]
points = Point3.(f.(ts))
lines!(ax, points)
fig

En el caso de figuras en 3D, es preferible utilizar los backend GLMakie.jl o WGLMakie.jl ya que permiten interaccionar con el el gráfico para visualizarlo desde distintas perspectivas.

fig = Figure()
ax = Axis3(fig[1, 1], title = "Diagrama de líneas 3D")
ts = range(0, 6pi, length = 200)
f(t) = [cos(t), sin(t), t/4]
points = Point3.(f.(ts))
lines!(ax, points)
fig

También es posible pasar a la función lines! un rango de valores y una función a dibujar. Esto simplifica la creación de gráficas de funciones.

  • lines(ax, rango, función): Dibuja en los ejes dados por ax la gráfica de la función dada en función en el intervalo dado por rango. El intervalo del rango se especifica con la sintaxis li..ls, donde li es el límite inferior y ls el límite superior.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
lines!(ax, 0..2pi, cos)
fig

Para añadir nuevas líneas al los ejes, basta con volver a usar la función lines!.

fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
lines!(ax, 0..2pi, cos)
lines!(ax, 0..3pi, sin)
fig

Los siguientes parámetros pueden añadirse a la función anterior para modificar el aspecto del diagrama de puntos.

  • linewidth: Establece el grosor de la línea de la gráfica.
  • linestyle: Establece el estilo de la línea de la gráfica.
  • color: Establece el color de la linea.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
lines!(ax, 0..2pi, cos, linewidth = 5, linestyle = :dash, color = :red)
lines!(ax, 0..2pi, sin, linestyle = :dot, color = :green)
fig

6.3.5 Superficies

Para dibujar superficies en 3D se utiliza la función

  • surface!(ax, xs, ys, zs): Dibuja en los ejes 3D dados por ax la superficie que se obtiene al unir los puntos con coordenadas \(x\) dadas por el vector xs, coordenadas y dadas por el vector ys y coordenadas \(z\) dadas por el vector zs.
using WGLMakie
WGLMakie.activate!()
fig = Figure()
ax = Axis3(fig[1, 1], title = "Superficie")
xs = ys = LinRange(0, 10, 100)
zs = [cos(x) * sin(y) for x in xs, y in ys]
WGLMakie.surface!(ax, xs, ys, zs)
fig

6.3.6 Leyenda

Si tenemos más de una serie de datos representada en un diagrama, conviene añadir una leyenda para identificar cada serie. Podemos añadir una leyenda con la función

  • axislegend(ax): Añade una leyenda a los ejes dados en ax, con las etiquetas de cada serie de datos incluida en los ejes. Para ello es necesario etiquetar cada serie de datos pasándole el parámetro label = etiqueta a la función que crea el objeto gráfico que representa la serie.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas con leyenda")
lines!(ax, 0..2pi, cos, label = "Coseno")
lines!(ax, 0..2pi, sin, label = "Seno")
axislegend()
current_figure()

6.4 Gráficos con GadFly.jl

GadFly.js es un paquete nativo que genera gráficos interactivos 2D y 3D por medio de librerías de Javascript basadas en la gramática de gráficos (usada también por el paquete ggplot2 de R).

Al estar implementado en Julia es mucho más rápido que Plots.js pero ofrece menos posibilidades.

6.5 Gráficos con VegaLite.jl

VegaLite.jl es un paquete que genera gráficos estáticos por medio de las librerías de Javascript de la gramática de gráficos Vega.

Dispone de muchas más opciones de personalización de gráficos que GadFly.jl.