Paquete Plots

begin
	using Pkg; Pkg.activate("."); Pkg.instantiate()
	using Pkg; Pkg.activate("."); ##Pkg.add("Plots") 
	using Plots
	theme(:wong)
end
 Activating environment at `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`
 Activating environment at `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`

Plots.jl

Plots.jl es un paquete en Julia que permite realizar diferentes tipos de trazados o gráficos, sin embargo, no es un paquete que realiza el trazado de forma estricta. Lo anterior significa que Plots.jl es un metapaquete y constituye una interfaz entre diferentes paquetes de trazado, simplificando trabajar con dichos paquetes.

Que Plots.jl sea un metapaquete es una ventaja, ya que solamente se necesita aprender la forma en que se realiza gráficos con Plots.jl y no las particularidades de los paquetes para realizar gráficos.

Por tanto, con Plots.jl es posible utilizar el mismo código para trabajar con diferentes paquetes de trazado. Los paquetes de trazado, en Plots.jl, se conocen como “backends” de los cuales se pueden mencionar:

Para conocer con cuál de los backends se está trabajando se utiliza la función backend:

backend()
Plots.GRBackend()

Pero, ya que se necesita correr de fondo un backend es necesario que éste sea instalado de la forma usual (Pkg.add('nombre_backend')) y sea invocado mediante una función que implementa Plots.jl.

##Pkg.add("GR");
##Pkg.add("Plotly");

Activar un backend se realiza de la siguiente forma:

begin
	plotly()
	backend();
end
┌ Info: For saving to png with the Plotly backend PlotlyBase has to be installed.
└ @ Plots /home/runner/.julia/packages/Plots/lmp2A/src/backends.jl:372
Plots.PlotlyBackend()
begin
	gr()
	backend();
end
Plots.GRBackend()

Comandos básicos

El comando más básico cuando se usa Plots.jl es plot. El comando plot admite diversas formas argumentos entrantes y dependiendo del caso se obtiene un determinado comportamiento.

Al igual que muchas funciones definidas en Julia, existe la versión mutante (plot!). La versión mutante permite modificar una determinada gráfica, añadiendo atributos u otro trazado.

begin
	x₁ = -10:0.1:10
	y₁ = x₁.^2
	plot₁ = plot(x₁,y₁)
end
_images/Paquete_Plots_11_0.svg

Los argumentos de plot son dos array: el primero x₁, constituye el eje horizontal; el segundo y₁ constituye el eje vertical. En plot₁ hay solo una serie graficada.

begin
	x₂ = -10:0.1:10
	series₂ = [100x₂.^2 5x₂.^3]
	plot₂ = plot(x₂, series₂)
end
_images/Paquete_Plots_13_0.svg

En el ejemplo anterior son graficadas dos series, los datos para cada serie están contenidos en las columnas de un array de dos dimensiones (en general, las columnas de un array serán interpretadas como series de datos).

A esta gráfica se le pueden añadir más series, para ello se utiliza la versión mutante de plot.

plot!(x₂, x₂.^4)
_images/Paquete_Plots_15_0.svg

La función mutante plot! actúa sobre la gráfica actual: Plots.CURRENT_PLOT, por ahora la gráfica actual es plot₂. La gráfica actual puede ser consultada mediante la función current().

current()
_images/Paquete_Plots_17_0.svg

Para que plot! actúe sobre un gráfico en específico, este debe ser pasado como argumento.

plot!(plot₁, x₁, x₁.^3)
_images/Paquete_Plots_19_0.svg

Ahora la gráfica actual es plot₁ modificada.

current()
_images/Paquete_Plots_21_0.svg

Para hacer una gráfica en el REPL de Julia se puede utilizar el backend unicodeplots().

Si se desea realizar una gráfica de 3 dimensiones, se pasa como parámetros tres arrays con los valores a graficar.

begin
	plot3d = plot(1:10,1:10,(1:10).^2)
end
_images/Paquete_Plots_23_0.svg

Atributos de los gráficos

Es natural que se desee agregar estilo a los gráficos, es decir, modificar o agregar: título, etiquetas a los ejes, controlar las marcas en el eje, etc. Todo lo anterior es manejado a través de atributos.

Los atributos se pueden pasar al gráfico de diferentes maneras:

  • Mediante la declaración explícita con atributo = valor.

  • Usando la función implementada al atributo atributo!(valor). En caso que se utilice la función es importante recordar que, como con plot!, se puede declarar de forma explícita la gráfica al cual se quiere modificar su atributo; si la gráfica no es declarada, se modifica la gráfica actual.

Los atributos pueden estar relacionados con: las gráficas (Plot), las series (Series), subgráficas (Subplot) y los ejes (Axis). En el REPL los diferentes atributos, pueden ser consultados mediante:

  • plotattr(:Plot)

  • plotattr(:Series)

  • plotattr(:Subplot)

  • plotattr(:Axis) Con los comandos anteriores solo se obtienen los nombres o alias de los atributos disponibles. Si se conoce el alias del atributo, se puede utilizar la función plotattr para obtener una descripción de ese atributo.

Los atributos de las gráficas, pueden ser consultados aquí. A continuación, se describen atributos que son usualmente usados.

Leyenda

begin
	x₃ = -2pi:0.1:2pi
	plotp₃ = plot(x₃, [sin, cos], label=["f₁(x)=sin(x)" "f₂(x)=cos()"])
end
_images/Paquete_Plots_26_0.svg

El atributo label permite nombrar cada serie de datos, apareciendo dicho nombre en la leyenda. Se pueden utilizar también palabras claves para referirse a los atributos, en el caso de label se puede usar: lab o labels. A diferencia de otros atributos, label, se declara cuando el gráfico es creado en la primera ocasión.

Las leyendas: el color, tamaño, tipo de letra y ubicación; puede ser modificado con los atributos: legendfontcolor, legendfontsize, legendfont y legend. El atributo legend acepta los siguientes valores: :none, :best, :inline, :inside, top, bottom, left, right; también acepta las siguientes combinaciones: :(outer ?)(top/bottom ?)(right/left ?).

Para obtener una mejor tipografía se puede utilizar el paquete “LaTeXStrings”, el cual permite escribir fórmulas matemáticas con el estilo de LaTeX.

begin
	##Pkg.add("LaTeXStrings")
	using LaTeXStrings
end
begin
	plot₃ = plot(x₃, [sin, cos], label=[L"f_1(x)=sin(x)"  L"f_2(x)=cos(x)"], legend=:topright, legendfontcolor=:gray, legendfontsize=10)
end
_images/Paquete_Plots_29_0.svg

Título

title!(plot₃,L"\textbf{Gráficas de } sin(x) \, \textbf{y} \, cos(x)", titlefontsize=20, titlefontcolor=:gray)
_images/Paquete_Plots_31_0.svg

El atributo title de utiliza para cambiar el nombre de la gráfica. Los atributos: titlefontsize y titlefontcolor modifican el tamaño y el color del título de la gráfica.

Ejes

plot!(plot₃, xlabel=L"\textbf{x}", ylabel=L"\textbf{y}") 
_images/Paquete_Plots_33_0.svg

Los atributos xlabel y ylabel se utilizan para etiquetar los ejes respectivamente. Si el gráfico fuera en tres dimensiones se puede etiquetar el eje de la tercera dimensión con zlabel.

Note que los atributos pueden ser modificados o agregados con la función plot!.

plot!(plot₃, xticks=(-2π:π:2π, ["-2π","-π","0","π","2π"]), xlims=(0,2π), xtickfontsize=10) 
_images/Paquete_Plots_35_0.svg

En el ejemplo anterior se modifican las etiquetas de las marcas del eje \(x\), para ello se utiliza el atributo xticks, el cual recibe como valor la secuencia de números que constituirán las marcas. En caso de querer etiquetar las marcas con alguna etiqueta personalizada, al atributo xticks se pasa una tupla conteniendo la secuencia y una lista de las marcas personalizadas.

Note que apesar que la gráfica se ha definido para ser graficada de -2π a , solamente se ha graficado de 0 a , ello es posible al indicar los límites del eje \(x\) con el atributo xlims que recibe una tupla conteniendo el límite inferior y superior.

Aunque no se mostrará, el eje \(y\) y el eje \(z\) (en caso que la gráfica sea de 3 dimensiones) puede ser modificado de manera similar que el eje \(x\). La diferencia será que, en lugar de colocar x antes de ticks o lims se deberá colocar el eje que se desea modificar (y o z).

Con el atributo xtickfontsize se modifica el tamaño de las etiquetas de las marcas del eje \(x\); como se explica en el párrafo anterior se puede modificar el eje \(y\) y \(z\).

Grilla

plot!(plot₃, gridlinewidth=4, gridcolor=:red, gridalpha=0.2, gridstyle=:dashdotdot)
_images/Paquete_Plots_37_0.svg

La grilla puede ser modificada con los atributos: gridlinewidth, gridcolor, gridalpha,gridstyle (acepta los valores :solid, :dash, :dot, :dashdot, :dashdotdot), que modifican respectivamente: el ancho de las líneas de la grilla, el color de la grilla, la intensidad del color de la grilla (por defecto se transparenta) y el estilo de las líneas de la grilla.

Si no se desea que la grilla aparezca, se debe asignar el valor de false al atributo grid (por defecto es true).

plot!(plot₃, grid=false)
_images/Paquete_Plots_39_0.svg

Otros

Para definir los atributos y por tanto el estilo de la gráfica una sola vez, en lugar de hacerlo cada ocasión que la gráfica que se construya, se puede utilizar la función default.

begin
	color = RGBA(190/255, 190/255, 190/255,1)
	default(titlefontsize=20, titlefontcolor=color, tickfontcolor=color, tickfontsize=9, legendfontcolor=color)
end

Tipos de serie

En todos los ejemplos anteriores se han graficado líneas (serie :line), para graficar un tipo específico, éste puede ser especificado mediante el atributo seriestype.

El atributo seriestype admite símbolos, que representan los diferentes tipos de gráficos o series. A continuación, se listan algunos tipos de serie:

  • :line

  • :scatter

  • :histogram

  • heatmap

  • :image

Pueden existir algunos tipos de series que no sean soportados por algunos backends, para conocer cuáles tipos de series son soportados por los backends, puede leer sobre ello aquí

Para cada serie, el paquete incorpora una función que llama directamente al tipo de serie y recibe el mismo nombre de la serie. También, incorpora una versión mutante y no mutante de dichas funciones.

Serie :line

Esta es la serie por defecto y la que une cada punto graficado con una línea.

plot(rand(1:100,30), title="Serie `line`", seriestype=:line)
_images/Paquete_Plots_43_0.svg
plot₄ = plot(rand(1:100,30), title="Serie `line`", markershape=:circ, linewidth=3, linecolor=:blue, linestyle=:dashdot, linealpha=0.5)
_images/Paquete_Plots_44_0.svg

En el ejemplo se muestra cómo personalizar la línea que es trazada, esto es, personalizar: el ancho de la línea, el color, el estilo de la línea y la transparencia de esta, mediante los atributos: linewidth, linecolor, linestyle y linealpha respectivamente. Los estilos de las líneas admitidos, ya fueron mencionados cuando se discutía el atributo grid.

En este último ejemplo, también se grafican los puntos que componen a la gráfica, más detalles sobre los atributos de las marcas se discuten en la siguiente sección.

Serie :scatter

plot([rand(20) rand(20) rand(20)], seriestype=:scatter, title="Serie 'scatter'", markershape=[:rect :circ :hex])
_images/Paquete_Plots_46_0.svg
plot₅ = scatter([rand(20) rand(20) rand(20)], title="Serie 'scatter'", markershape=[:star  :diamond :ltriangle], markerstrokecolor=:red, markercolor=[:orange :green :darkblue], markeralpha=[0.5 1 0.2],  markersize= [3 7 12])
_images/Paquete_Plots_47_0.svg

En los ejemplos anteriores han sido realizados graficos de dispersión. Para dar estilo al gráfico, se han añadido atributos que personalizan las marcas que representan los datos.

makershape es el atributo que permite modificar la forma de la marca, para saber las distintas formas admitidas puede revisar este enlace. markerstrokecolor permite modificar el color del borde de la marca. markercolor permite modificar el color de la marca. markeralpha permite agregar transparencia al color de la marca. markersize permite modificar el tamaño de la marca. Para conocer el resto de atributos relacionados con los gráficos de dispersión, puede revisar el siguiente enlace.

Serie :histogram

Con esta serie es posible crear histogramas.

 plot(rand(1:20,50), title="Serie 'histogram'",seriestype=:histogram)
_images/Paquete_Plots_50_0.svg
plot₆ = histogram(rand(1:20,100), title="Serie 'histogram'", normalized=true, bins=(0:21), orientation=:v, bar_width=1, color=[:red,:orange,:green], xticks=(1.5:21.5,["$i" for i  1:20]), legend=:none)
_images/Paquete_Plots_51_0.svg

Para esta serie, los siguientes atributos aplican: normalized, que permite la altura de las barras se encuentre entre los valores 0 y 1; bins, permite indicar los valores de las etiquetas del eje \(x\) y finalmente las barras que serán graficadas; orientation, permite graficar las barras de forma vertical u horizontal; bar_width, permite modificar el ancho de la barra; color, permite graficar las barras con diferentes colores.

En el ejemplo se utiliza el atributo xticks para modificar las etiquetas asociada a cada gráfica.

Serie :heatmap

Con esta serie se pueden crear mapas de calor. Para ello, se especifican los puntos del plano pasando como parámetros los puntos del eje \(x\) y \(y\), además, se pasa como parámetro una matriz (array) que define un valor numérico para cada punto del plano que es graficado en el mapa de calor.

plot(1:10, 1:10, [i*y for i  1:10, y  1:10], title="Serie 'heatmap'", seriestype=:heatmap)
_images/Paquete_Plots_54_0.svg
plot₇ = heatmap(1:0.03:10, 1:0.03:10, [i*y for i  1:0.03:10, y  1:0.03:10], title="Serie 'heatmap'", color=cgrad([:black, :orange, :red, :blue]))
_images/Paquete_Plots_55_0.svg

En el ejemplo anterior se utiliza el atributo color para establecer el color del mapa de calor. La función cgrad permite crear nuesta propia paleta de colores, aunque Julia incorpora paletas y gradientes decolores, más de ello puede conocer aquí.

Serie :image

Una imagen puede mostrarse con la serie image. Para cargar la imagen en el proyecto se puede hacer con el método load del paquete Images.

## Pkg.add("Images"); Pkg.add("ImageMagick");
using Images
begin
	im = load("images/julia.jpg")
	plot₈ = plot(im, seriestype=:image, title="Serie 'image'", ticks=false)
end
_images/Paquete_Plots_60_0.svg

Creando subgráficas

Las librerías de trazado, por lo general implementan formas de combinar varias gráficas como subgráficas. Con el paquete Plots se pueden crear diversos diseños, siendo el más sencillo de utilizar el diseño de malla o grilla.

El diseño puede ser creado asignando una tupla, con las dimensiones de la grilla, al atributo layout.

plot(plot₆, plot₇, layout=(2,1))
_images/Paquete_Plots_62_0.svg

Diseños más complejos pueden ser creados con la macro @layout, para más información revisar Layouts.

Guardando una gráfica

Para obtener una imagen con la gráfica realizada, se utiliza la función savefig, los argumentos que admiten son:

  • El nombre con el que se desea guardar la imagen, junto con la extensión.

  • El gráfico que se desea guardar. Si no se especifica el gráfico, se guarda el gráfico actual (Plots.CURRENT_PLOT). Hay que tener en cuenta que la extensión del archivo a guardar, depende del backend que se está usando ya que no todos admiten la misma extensión.

Referencias e información adicional

El paquete de Julia ha sido extendido, en su funcionalidad y aplicación, mediante el desarrollo de diferentes paquetes que constituyen un entorno muy completo para los gráficos, una revisión rápida del ambiente de Julia para gráficos puede encontrarlo aquí.

Referencias e información interesante puede encontrar en los siguientes enlaces: