No hace falta dibujar una gráfica de tus datos o de una función en un programa externo y pegarla como imagen. LaTeX tiene una forma de construir el gráfico a partir de los datos dentro del documento. El protagonista es pgfplots, construido sobre TikZ/PGF. A partir de una función, de coordenadas o de un archivo de datos, dibuja gráficas de líneas y dispersión, diagramas de barras e incluso superficies 3D, todo con las mismas fuentes y grosores de línea que el texto. Esta página se centra en el entorno axis de pgfplots y en \addplot, y luego cubre el uso de gnuplot como calculadora externa y la importación de gráficos hechos en R o Python (matplotlib) como código TikZ.
Por qué componer gráficos dentro del documento
Pegar un PNG hecho en una hoja de cálculo o una aplicación de dibujo suele chocar con el documento: las etiquetas de los ejes tienen otra tipografía, las ecuaciones llegan como imágenes borrosas y las líneas se vuelven dentadas al ampliar. Si corriges los datos, hay que rehacer y volver a pegar la figura. pgfplots invierte la idea y deja que LaTeX componga el gráfico. Los números de los ejes y la leyenda usan la misma fuente que el texto, las curvas son vectoriales y se mantienen suaves a cualquier zoom, y una etiqueta puede contener matemáticas reales como $\sin x$.
Una segunda ventaja es la separación de los datos. En lugar de codificar coordenadas en el cuerpo, apuntas pgfplots a un archivo .dat o .csv; después basta con actualizar los datos y recompilar para que el gráfico cambie. Puedes reutilizar los mismos números en un artículo, diapositivas y un apéndice sin errores de transcripción. Es exactamente la idea de construir tablas a partir de datos (véase relacionado), y pgfplots incluye el paquete hermano pgfplotstable para tablas.
pgfplots está construido sobre TikZ/PGF, así que toda la figura vive dentro de un entorno tikzpicture y puedes mezclar libremente coordenadas, nodos y decoraciones de TikZ. Los fundamentos de TikZ (\draw, el sistema de coordenadas, los nodos) se dejan para la página “TikZ basics”; aquí nos centramos en graficar.
El esqueleto de pgfplots — axis y \addplot
Primero cárgalo en el preámbulo y declara un nivel de compatibilidad. Escribir \pgfplotsset{compat=1.18} fija el comportamiento por defecto de esa versión (aspecto de los ejes, colocación de marcas, etc.) para que una futura actualización de pgfplots no cambie tus figuras en silencio. En documentos nuevos se acostumbra usar el número más reciente que permita la versión instalada.
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}En el cuerpo colocas un entorno axis dentro de un tikzpicture, y cada llamada a \addplot dentro añade una curva más. Los ejes, marcas, rejilla y leyenda se configuran con opciones de axis; el color y los marcadores de cada curva, con opciones de \addplot. Aquí tienes un ejemplo mínimo.
\begin{tikzpicture}
\begin{axis}[
xlabel = {$x$},
ylabel = {$f(x)$},
title = {A parabola},
grid = major,
]
\addplot[blue, domain=-3:3, samples=100] {x^2};
\addlegendentry{$x^2$}
\end{axis}
\end{tikzpicture}Esto muestrea la parábola y = x² en 100 puntos sobre −3 ≤ x ≤ 3 y la dibuja como una curva azul suave. Los ejes llevan etiquetas x y f(x), arriba aparece el título “A parabola”, grid=major pone una rejilla tenue sobre las marcas principales, y \addlegendentry añade la entrada de leyenda “x²”. Veamos los puntos clave.
- Encierra etiquetas y títulos entre llaves. Escribirlos como
xlabel={$x$}permite poner dentro matemáticas o comas sin problemas. ^es potencia; la trigonometría usa grados por defecto. La expresión en\addplot {x^2}la evalúa el analizador interno de pgf. Funciones como\sintoman el argumento en grados, así que para pasar radianes envuélvelo comosin(deg(x))condeg().domainysamples. Un gráfico de función muestrea el intervalodomain=a:bconsamples=Npuntos (los valores por defecto son aproximadamente −5:5 y 25 puntos). Si la curva se ve angular, subesamples.- Dos formas de hacer leyendas. Coloca
\addlegendentry{…}después de cada curva, o escríbelas juntas en las opciones deaxiscomolegend entries={A,B,...}. Ubícala conlegend pos=north west, etc.
Las opciones de axis más usadas se reúnen abajo. Van dentro del [...] de axis, separadas por comas.
| Opción | Qué hace |
|---|---|
xlabel= / ylabel= | Etiquetas de los ejes x e y; encierra con llaves como xlabel={$x$}, admite matemáticas |
title= | Un título colocado sobre el gráfico |
xmin= xmax= ymin= ymax= | Fijar el rango visible (los límites de los ejes) |
grid= | Dibujar rejillas: grid=major en marcas principales, grid=both también en menores |
legend pos= | Posición de la leyenda: north west, etc.; outer north east la coloca fuera de los ejes |
xtick= | Indicar dónde van las marcas (p. ej. xtick={0,1,2}); xtick=data las alinea con los datos |
width= / height= | Definir las dimensiones de la figura |
ybar | Convertirlo en gráfico de barras verticales (abajo); xbar para horizontal |
Tres formas de aportar datos — función, coordenadas, archivo
\addplot acepta datos de tres formas generales. La primera, vista arriba, es a partir de una función: pones una expresión en {...} y pgfplots la muestrea sobre domain para formar una curva.
\addplot[red, domain=0:2*pi, samples=200] {sin(deg(x))};Esto dibuja una curva seno de 0 a 2π. Como x está en radianes, la clave es el envoltorio deg(), que lo convierte a grados antes de que llegue a \sin, que trabaja en grados.
La segunda es a partir de coordenadas en línea: enumera pares (x,y) en coordinates {...} y pgfplots une los puntos en orden como una línea o, con solo marcadores, como una dispersión. Es cómodo cuando tienes pocos valores medidos.
\addplot[mark=*, blue] coordinates {
(0,0) (1,1) (2,4) (3,9) (4,16)
};Aquí cinco puntos se unen con una línea azul y cada uno lleva un marcador circular relleno (mark=*). Para quitar la línea y dejar solo los puntos, usa only marks; cambia el estilo de línea con dashed y similares.
La tercera, la más importante en la práctica, es a partir de un archivo de datos. table {filename} lee un archivo de texto separado por espacios. La primera línea nombra las columnas (la cabecera), y por defecto pgfplots dibuja la columna 1 como x y la columna 2 como y. Supón que tienes este data.dat.
x y
0 0.0
1 0.8
2 0.9
3 0.1
4 -0.8
5 -1.0\begin{tikzpicture}
\begin{axis}[xlabel={$x$}, ylabel={$y$}, grid=major]
\addplot[mark=square, teal] table {data.dat};
% 列名で明示するなら:
% \addplot table[x=x, y=y] {data.dat};
\end{axis}
\end{tikzpicture}Para ser explícito, nombra las columnas como en table[x=x, y=y] {data.dat}; los nombres distinguen mayúsculas. Para un CSV separado por comas usa table[col sep=comma]{...}; las líneas que empiezan por # o % se saltan como comentarios. Cuando necesites transformar datos o derivar columnas calculadas, está el paquete hermano pgfplotstable (véase “Tables from data”).
Barras, ejes logarítmicos y 3D
El mismo marco axis/\addplot puede cambiar cómo se muestran los datos. Para un diagrama de barras, basta con dar a axis la opción ybar (barras verticales). Si apilas varias llamadas a \addplot, se desplazan automáticamente para formar barras agrupadas.
\begin{tikzpicture}
\begin{axis}[
ybar,
xlabel = {Year}, ylabel = {Count},
symbolic x coords = {2023, 2024, 2025},
xtick = data,
]
\addplot coordinates {(2023,40) (2024,55) (2025,72)};
\end{axis}
\end{tikzpicture}Aquí los años (cadenas) se usan como etiquetas del eje x mediante symbolic x coords, y xtick=data alinea las marcas con cada punto de datos. Para barras horizontales, usa xbar.
Los ejes logarítmicos se obtienen simplemente cambiando axis por otro nombre de entorno: loglogaxis para log–log, semilogxaxis solo para eje x logarítmico, y semilogyaxis solo para y. El \addplot interior no cambia.
\begin{tikzpicture}
\begin{loglogaxis}[xlabel={$x$}, ylabel={$y$}]
\addplot[domain=1:1000, samples=50] {1/x};
\end{loglogaxis}
\end{tikzpicture}Para 3D, usa \addplot3 y axis se vuelve tridimensional automáticamente. Especifica surf para una superficie o mesh para una malla, y escribe la función en las dos variables x e y. La 3D desde coordenadas o desde un archivo de datos funciona igual mediante \addplot3.
\begin{tikzpicture}
\begin{axis}[xlabel={$x$}, ylabel={$y$}, zlabel={$z$}]
\addplot3[surf, samples=30, domain=-3:3]
{exp(-x^2 - y^2)};
\end{axis}
\end{tikzpicture}Esto dibuja la superficie gaussiana en forma de campana z = e^(−x²−y²) sobre una rejilla 30×30 como superficie coloreada. Gira el punto de vista con view={azimuth}{elevation}.
Usar gnuplot como calculadora
El analizador propio de pgfplots es cómodo, pero puede quedarse corto con expresiones complicadas o muchas muestras. Al escribir \addplot gnuplot {...}, el trabajo numérico pasa al programa externo gnuplot, que calcula las coordenadas; luego pgfplots las lee y dibuja. En efecto, gnuplot se usa como “calculadora de escritorio”.
\begin{tikzpicture}
\begin{axis}[xlabel={$x$}, ylabel={$y$}]
\addplot[blue] gnuplot[domain=0:10] {sin(x)};
\end{axis}
\end{tikzpicture}Hay dos advertencias importantes. Primero, --shell-escape es obligatorio: como LaTeX lanza un comando externo (gnuplot), debes compilar con la ejecución de comandos externos activada, como en pdflatex --shell-escape document (también llamado -write18); si no, no se ejecutará. Durante el proceso se generan archivos intermedios para gnuplot, se escriben allí los resultados y se leen de vuelta.
Segundo, la sintaxis cambia: las expresiones enviadas a gnuplot las evalúa su propio motor matemático, así que el operador de potencia es el `** de gnuplot, no el ^ de pgfplots, y las funciones trigonométricas usan **radianes** por defecto. Por tanto, la “misma” curva seno se escribe {sin(deg(x))} con el analizador integrado, pero {sin(x)} mediante gnuplot. Como --shell-escape` está desactivado por defecto por seguridad, añádelo solo cuando lo necesites.
Importar gráficos de R y Python
Ya hiciste el análisis en R o Python y quieres reutilizar sus gráficos, pero sin los defectos de las imágenes pegadas (fuentes que no coinciden, ecuaciones borrosas). La solución es hacer que cada herramienta emita código TikZ/pgfplots, de modo que el gráfico se componga como parte del documento, con fuentes y matemáticas iguales al cuerpo.
En R, el paquete tikzDevice proporciona un “dispositivo gráfico” que escribe la salida gráfica estándar de R, incluidos gráficos base y ggplot2, como código TikZ. Abre el dispositivo con tikz(), ejecuta tu código de dibujo habitual y ciérralo con dev.off() para obtener un archivo .tex. Como consulta a LaTeX los anchos de cadenas y métricas de fuente al colocar texto, la salida coincide exactamente con la tipografía del cuerpo, y puedes poner matemáticas de LaTeX en las etiquetas de ejes. Con standAlone=TRUE emite un documento completo compilable por separado.
library(tikzDevice)
tikz("plot.tex", width = 4, height = 3)
plot(cars$speed, cars$dist,
xlab = "Speed", ylab = "Distance")
dev.off()En Python (matplotlib), tikzplotlib (antes matplotlib2tikz) convierte una figura hecha con matplotlib.pyplot en código pgfplots. Escríbela con tikzplotlib.save("figure.tex") e inclúyela en LaTeX con \input{figure.tex}. Ten en cuenta que tikzplotlib ya no se mantiene; un fork, matplot2tikz, se desarrolla como sucesor. Para trabajos nuevos, considera matplot2tikz; la API es casi la misma.
import matplotlib.pyplot as plt
import tikzplotlib # or: import matplot2tikz
plt.plot([0, 1, 2, 3], [0, 1, 4, 9])
plt.xlabel("$x$")
plt.ylabel("$x^2$")
tikzplotlib.save("figure.tex")Cualquiera de las dos rutas produce un .tex que usa pgfplots internamente, así que el documento también necesita \usepackage{pgfplots} y \pgfplotsset{compat=...}. Poder ajustar a mano el código generado es otra ventaja que un archivo de imagen no ofrece.
Rendimiento y externalización
pgfplots es bonito, pero lento y hambriento de memoria con datos grandes: una dispersión de decenas de miles de puntos puede alargar la compilación o alcanzar los límites de memoria de TeX. Hay varios remedios.
- Reducir los puntos. Dibuja cada k-ésimo punto con
each nth point=k, o descarta datos fuera de rango con filtros comofilter discard if not. - Externalización. Con
\usepgfplotslibrary{external}y\tikzexternalize, cada figura se compila una vez en su propio PDF y después solo se incluye, aligerando las recompilaciones del cuerpo (necesita--shell-escape). - Un motor con más memoria.
LuaLaTeXtiene límites de memoria más holgados y conviene para figuras grandes. - Pre-renderizar antes. Si un gráfico sigue siendo demasiado pesado, importar el resultado dibujado en R, Python o gnuplot (sección anterior) puede ser más práctico.
Las funciones que necesitan --shell-escape, como la externalización o gnuplot, deben activarse al compilar en CI o en un contenedor. Consulta la página relacionada sobre Docker / CI setup.