
A menudo hago gráficos para mis cursos y encuentro que siempre estoy copiando y pegando código y quiero acelerar las cosas. Utilizo mi propio .cls
archivo para mi código, así que tal vez podría almacenar algunas de estas configuraciones de uso frecuente allí.
Aquí está miactualcódigo para un gráfico típico:
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=.9]
\def \xmin {-3}
\def \xmax {3}
\def \ymin {-2}
\def \ymax {3}
\draw[help lines] (\xmin, \ymin) grid (\xmax, \ymax);
\draw [<->] (\xmin-.3,0) -- (\xmax+.3,0);
\draw [<->] (0,\ymin-.3) -- (0,\ymax+.3);
\node at (0,\ymax + .6) {$g(x)$};
\node at (\xmax + .6,0) {$x$};
\node at (-2, 1.5) {$y = g(x)$};
\draw[domain=-1.828:1, blue, very thick, smooth] plot
({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, blue, very thick, smooth] plot
({\x}, {-1*(\x-1)^2 + 1});
\draw[very thick, blue, fill] (1,1) circle [radius=.08];
\draw[very thick, blue, fill=white] (1,2) circle [radius = .08];
\foreach \x in {1} \draw (0,\x)node[right]{\x};
\foreach \x in {1} \draw (\x,0)node[below]{\x};
\end{tikzpicture}
\end{document}
Cosas que son repetitivas:
- Los estilos de línea son siempre "muy gruesos, azules".
- Siempre dibujo líneas de ayuda especificadas por los valores anteriores.
- Los círculos (rellenos de blanco o azul) son comunes
- Utilizo los dos últimos comandos para agregar etiquetas.
Algunas cosas no escalan bien. Si configuro la escala en .5, por ejemplo, las flechas no se verán correctas y el texto se moverá. Me pregunto si puedo cambiar la posición de las flechas y las etiquetas en los ejes según el factor de escala.
Si tienes alguna idea sobre esto, te lo agradecería mucho. Creo que estoy superado en términos de archivos tikz y de clase.
Respuesta1
Puede usar \tikzset
y \newcommand
para crear el código común para colocar en su .cls
archivo.
Por ejemplo, he creado:
- un
myblue
estilo que puedes usar en lugar de "azul muy grueso" - un
myhelp
comando para las líneas de ayuda - a
whitepoint
ybluepoint
pic
s para los círculos (rellenos de blanco o azul, también puedes crear uno únicopic
con un parámetro para pasar la opción de color) - un
mylabels
comando para agregar las etiquetas.
Vea el código para saber cómo usarlos:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,shapes.symbols,positioning,decorations.pathmorphing}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% you may put a code like this in your .cls file
\tikzset{%
myblue/.style={blue, very thick},
pics/bluepoint/.style={code={%
\draw[very thick, blue, fill] (0,0) circle [radius=.08];
}},
pics/whitepoint/.style={code={%
\draw[very thick, blue, fill=white] (0,0) circle [radius = .08];
}},
}
\newcommand{\myhelp}{\draw[help lines] (\xmin, \ymin) grid (\xmax, \ymax);}
\newcommand{\mylabels}{%
\foreach \x in {1} \draw (0,\x)node[right]{\x};
\foreach \x in {1} \draw (\x,0)node[below]{\x};}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}[scale=.9]
\def \xmin {-3}
\def \xmax {3}
\def \ymin {-2}
\def \ymax {3}
\myhelp
\draw [<->] (\xmin-.3,0) -- (\xmax+.3,0);
\draw [<->] (0,\ymin-.3) -- (0,\ymax+.3);
\node at (0,\ymax + .6) {$g(x)$};
\node at (\xmax + .6,0) {$x$};
\node at (-2, 1.5) {$y = g(x)$};
\draw[domain=-1.828:1, myblue, smooth] plot
({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, myblue, smooth] plot
({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,1) {bluepoint};
\pic at (1,2) {whitepoint};
\mylabels
\end{tikzpicture}
\end{document}
Por supuesto, el resultado es exactamente el mismo:
Si puede ser útil, esta es la versión con una opción paramétrica para el color de la punta de la flecha, con blue
por defecto:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,shapes.symbols,positioning,decorations.pathmorphing}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% you may put a code like this in your .cls file
\tikzset{%
myblue/.style={blue, very thick},
pics/mypoint/.style={code={%
\draw[very thick, blue, fill=#1] (0,0) circle [radius=.08];
}},
pics/mypoint/.default=blue
}
\newcommand{\myhelp}{\draw[help lines] (\xmin, \ymin) grid (\xmax, \ymax);}
\newcommand{\mylabels}{%
\foreach \x in {1} \draw (0,\x)node[right]{\x};
\foreach \x in {1} \draw (\x,0)node[below]{\x};}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}[scale=.9]
\def \xmin {-3}
\def \xmax {3}
\def \ymin {-2}
\def \ymax {3}
\myhelp
\draw [<->] (\xmin-.3,0) -- (\xmax+.3,0);
\draw [<->] (0,\ymin-.3) -- (0,\ymax+.3);
\node at (0,\ymax + .6) {$g(x)$};
\node at (\xmax + .6,0) {$x$};
\node at (-2, 1.5) {$y = g(x)$};
\draw[domain=-1.828:1, myblue, smooth] plot
({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, myblue, smooth] plot
({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,1) {mypoint};
\pic at (1,2) {mypoint=white};
\mylabels
\end{tikzpicture}
\end{document}
Respuesta2
Un enfoque es utilizar \pgfkeys
para almacenar varios valores predeterminados para sus gráficos y luego envolver todo dentro de un entorno personalizado, con nuevas configuraciones proporcionadas a través de pares clave-valor. Por ejemplo, el código
\pgfkeys{/mygraph/.is family, /mygraph,
xmin/.initial = -3, % defaults for xmin, xmax, ymin,ymax
xmax/.initial = 3,
ymin/.initial = -3,
ymax/.initial = 3,
ylabel/.initial = f(x),% default function name
scale/.initial = 0.9, % tikzpicture scale
xtics/.initial = {1}, % list of marked coordinates on x-axis
ytics/.initial = {1}, % list of marked coordinates on y-axis
}
establece valores iniciales (o predeterminados) para los valores máximo y mínimo de x e y, la etiqueta para el eje y y la escala. Luego puede definir un entorno, digamos MyGraph
que toma un argumento opcional, que se pasa a \pgfkeys
través de
\pgfkeys{/mygraph, #1}
para cambiar esta configuración. Esto se utilizaría como
\begin{MyGraph}[ylabel=g(x)]
\draw[domain=-1.828:1, smooth,-{Circle[blue]}] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth, {Circle[open, fill=white]}-] plot ({\x}, {-1*(\x-1)^2 + 1});
\end{MyGraph}
¡Esto dibuja el gráfico en la pregunta! En particular, cabe señalar que \usetikzlibrary{arrows.meta}
proporciona puntas de "flecha" circulares. En general, los "contenidos" del MyGraph
entorno serán el material específico de su gráfico.
El MyGraph
entorno abriría el tikzpicture
entorno y dibujaría el "código inicial". Aquí hay una posible definición:
\newenvironment{Mygraph}[1][]%
{\pgfkeys{/mygraph, #1}% process settings
\begin{tikzpicture}[scale=\Gval{scale},
draw/.append style={very thick, blue}]
\draw[help lines](\Gval{xmin},\Gval{ymin}) grid (\Gval{xmax},\Gval{ymax});
\draw[thin, black] [<->] (\Gval{xmin}-0.3,0) -- (\Gval{xmax}+0.3,0);
\draw[thin, black] [<->] (0,\Gval{ymin}-0.3) -- (0,\Gval{ymax}+0.3);
\node at (0,\Gval{ymax} + .6) {$\Gval{ylabel}$};
\node at (\Gval{xmax} + .6,0) {$x$};
\node at (-2, 1.5) {$y = \Gval{ylabel}$};
}
{\end{tikzpicture}}
(La \Gval
macro, que es un acceso directo a \pgfkeysvalueof{/mygraph/#1}
, extrae el valor de la clave correspondiente).
Observe draw/.append style={very thick, blue}
al inicio del tikzpicture
entorno: esto establece líneas azules gruesas como valor predeterminado para el \draw
comando. Hay una pequeña desventaja de hacerlo de esta manera ya que ahora es necesario escribir \draw[black]....
las etiquetas en los ejes xey. Otra forma de hacerlo sería utilizar
\tikzset
para definir un estilo:
\tikzset{% define styles for commonly used elements
myline/.style={very thick, blue}
}
y luego usarías \draw[myline]...
cuando quisieras tus gruesas líneas azules. El uso \tikzset
es más explícito y, por lo tanto, probablemente mejor, pero si desea que "casi todos" sus comandos de dibujo den líneas azules gruesas, esto le ahorrará tener que escribir.
Aquí hay un MWE completo que utiliza el MyGraph
entorno para dibujar dos gráficos "diferentes":
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
% Using pgfkeys makes it easier to use key-value settings for the graph
\pgfkeys{/mygraph/.is family, /mygraph,
xmin/.initial = -3, % defaults for xmin, xmax, ymin,ymax
xmax/.initial = 3,
ymin/.initial = -3,
ymax/.initial = 3,
ylabel/.initial = f(x),% default function name
scale/.initial = 0.9, % tikzpicture scale
xtics/.initial = {1}, % list of marked coordinates on x-axis
ytics/.initial = {1}, % list of marked coordinates on y-axis
}
% shortcut to access values of /mygraph
\newcommand\Gval[1]{\pgfkeysvalueof{/mygraph/#1}}
% graph environment with optional argument for changing defaults
\newenvironment{Mygraph}[1][]%
{\pgfkeys{/mygraph, #1}% process settings
\begin{tikzpicture}[scale=\Gval{scale},
draw/.append style={very thick, blue}]
\draw[help lines](\Gval{xmin},\Gval{ymin}) grid (\Gval{xmax},\Gval{ymax});
\draw[thin, black] [<->] (\Gval{xmin}-0.3,0) -- (\Gval{xmax}+0.3,0);
\draw[thin, black] [<->] (0,\Gval{ymin}-0.3) -- (0,\Gval{ymax}+0.3);
\node at (0,\Gval{ymax} + .6) {$\Gval{ylabel}$};
\node at (\Gval{xmax} + .6,0) {$x$};
\node at (-2, 1.5) {$y = \Gval{ylabel}$};
\xdef\xtics{\Gval{xtics}}% for reasons unknown can't use this directly
\foreach \x in \xtics { \draw[black](\x,0)node[below]{\small$\x$}; }
\xdef\ytics{\Gval{ytics}}
\foreach \y in \ytics { \draw[black](0,\y)node[left]{\small$\y$}; }
}
{\end{tikzpicture}}
\begin{document}
\begin{Mygraph}
\draw[domain=-1.828:1, smooth,-{Circle[blue]}] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth, -{Circle[open, fill=white]}] plot ({\x}, {-1*(\x-1)^2 + 1});
\end{Mygraph}
\begin{Mygraph}[ylabel=g(x), xmin=-4, xmax=4, scale=0.5, xtics={1,2,3}, ytics={1,3}]
\draw[domain=-1.828:1, smooth,-{Circle[blue]}] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth, {Circle[open,fill=white]}-] plot ({\x}, {-1*(\x-1)^2 + 1});
\end{Mygraph}
\end{document}
Aquí está el resultado:
Por supuesto, puede agregar más configuraciones para \pgfkeys{/mygraph/,...}
personalizar aún más sus gráficos. Por ejemplo, probablemente quieras hacer esto para los valores x e y etiquetados en los ejes y la ubicación de la y=g(x)
etiqueta, etc. También hay muchas otras cosas que puedes hacer con\pgfkeys
: consulte latikzmanual para obtener más información.
Respuesta3
Las respuestas anteriores de @andrew y @CarLaTeX son constructivas e instructivas. He adoptado partes de ambas respuestas para generar el siguiente código.
En mi archivo de clase, tengoagregadolo siguiente, a una cantidad ya sustancial de código (no relacionado). No quiero publicar todo aquí, por lo que las partes relevantes son:
% This is the setup for the wcgraph environment below
\tikzset{%
myblue/.style={blue, very thick},
pics/closed/.style={code={%
\draw[very thick, blue, fill] (0,0) circle [radius=.08];
}},
pics/open/.style={code={%
\draw[very thick, blue, fill=white] (0,0) circle [radius=.08];
}},
pics/mypoint/.default=blue,
draw/.append style={very thick, blue},
>=latex,
>=stealth,
}
% This is the setup for the wcgraph environment below
\pgfkeys{/mygraph/.is family, /mygraph,
xmin/.initial = -3, % defaults for xmin, xmax, ymin,ymax
xmax/.initial = 3,
ymin/.initial = -3,
ymax/.initial = 3,
ylabel/.initial = f(x), % default function name
xlabel/.initial = x, % default independent variable
scale/.initial = 0.9, % tikzpicture scale
xtics/.initial = {1}, % list of marked coordinates on x-axis
ytics/.initial = {1}, % list of marked coordinates on y-axis
xticsloc/.initial = below, % default location for tick labels
yticsloc/.initial = left,
helplines/.initial = draw, % Default to draw the help lines
}
% A new command to grab values from pgfkeys above
\newcommand\getVal[1]{\pgfkeysvalueof{/mygraph/#1}}
% A command to draw helplines. To not draw them, pass the option "hide"
\newcommand{\helplines}[1]{
\ifthenelse{\equal{#1}{draw}}{
\draw[help lines] (\getVal{xmin},\getVal{ymin}) grid (\getVal{xmax},\getVal{ymax});
}{}
}
% The graph environment with optional arguments for changing defaults
\newenvironment{wcgraph}[1][]%
{\pgfkeys{/mygraph, #1}% process settings
\begin{tikzpicture}[scale=\getVal{scale}]
\helplines{\getVal{helplines}}
\draw[thin, black] [->] (\getVal{xmin}-0.3,0) -- (\getVal{xmax}+0.3,0);
\draw[thin, black] [->] (0,\getVal{ymin}-0.3) -- (0,\getVal{ymax}+0.3);
\node at (0,\getVal{ymax} + .6) {$\getVal{ylabel}$};
\node at (\getVal{xmax} + .6,0) {$\getVal{xlabel}$};
\xdef\xtics{\getVal{xtics}} % Can't use this directly for some reason
\foreach \x in \xtics {
\draw[black](\x,0)node[\getVal{xticsloc}]{\small$\x$};
}
\foreach \x in {\getVal{xmin},...,\getVal{xmax}}{
\draw[black, thin, shift={(\x,0)}] (0pt,1pt) -- (0pt,-1pt);
}
\xdef\ytics{\getVal{ytics}}
\foreach \y in \ytics {
\draw[black](0,\y)node[left]{\small$\y$};
}
\foreach \y in {\getVal{ymin},...,\getVal{ymax}}{
\draw[black, thin, shift={(0,\y)}] (1pt,0pt) -- (-1pt,0pt);
}
}
{\end{tikzpicture}}
En mi .tex
archivo, uso la worksheet.cls
clase que (como dije anteriormente) incluye muchas otras cosas además de las que publiqué directamente encima de esto. Una MWE es:
\documentclass{worksheet}
\begin{document}
\begin{wcgraph}[xmin=-2, ymin=-2]
\draw[domain=-1.828:1, smooth] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth] plot ({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,2) {open};
\pic at (1,1) {closed};
\end{wcgraph}
\begin{wcgraph}[helplines=hide, xmin=-2, ymin=-2, scale=1.8]
\draw[domain=-1.828:1, smooth] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth] plot ({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,2) {open};
\pic at (1,1) {closed};
\end{wcgraph}
\end{document}
lo que produce los siguientes gráficos:
Quizás este no sea el lugar para hacer una pregunta de seguimiento (y estaré encantado de editarla y publicar otra pregunta si alguien lo sugiere), pero me gustaría ampliar un poco las cosas. Creo que esto es muy relevante para la pregunta original y, por tanto, para el seguimiento. Quiero agregar un comando para dibujar todos los nodos "abiertos" necesarios especificando coordenadas. Tengo problemas para pasar una "lista" de coordenadas en el nuevo comando. Quiero usar \foreach
on #1
, el argumento de mi nuevo comando. Esto no funciona como esperaba y no se analizará como coordenadas. He leído la guía PGF y muchas publicaciones \foreach
sin éxito.
Me gustaría utilizar el siguiente código para graficar lo anterior:
\begin{wcgraph}[helplines=hide, xmin=-2, ymin=-2, scale=1.8]
\draw[domain=-1.828:1, smooth] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth] plot ({\x}, {-1*(\x-1)^2 + 1});
\openpics{(1,2)};
\closedpics{(1,1)};
\end{wcgraph}
lo cual sería de gran beneficio cuando tenga gráficos más complejos.
Mi mejor suposición sobre este nuevo comando (que se agregará a mi .cls
archivo):
% A new command to draw all open pics I need.
\newcommand{\openpics}[1]{
\foreach \coord in {#1}{
\pic at \coord {open};
}
}
Y el \closedpics
comando sería similar.
Respuesta4
Es posible que desee considerar el pgfplots
paquete para su propósito; a continuación se muestra un ejemplo completo.
% arara: pdflatex
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{every axis/.append style={
axis x line=middle,
axis y line=middle,
axis line style={<->},
xlabel={$x$},
ylabel={$y$},
line width=1pt,},
% line style
gnatplot/.style={color=blue,mark=none},
soldot/.style={color=blue,only marks,mark=*},
holdot/.style={color=blue,fill=white,only marks,mark=*},
}
% arrows
\tikzset{>=stealth}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-3,xmax=3,
ymin=-2,ymax=3,
grid=both,
]
\addplot[gnatplot,domain=-1.828:1]{-0.5*(x-1)^2 + 2};
\addplot[gnatplot,domain=1:2.732]{-1*(x-1)^2 + 1};
\addplot[soldot]coordinates{(1,1)};
\addplot[holdot]coordinates{(1,2)};
\end{axis}
\end{tikzpicture}
\end{document}