¿Cómo puedo configurar explícitamente el ancla de la etiqueta TikZ?

¿Cómo puedo configurar explícitamente el ancla de la etiqueta TikZ?

Quiero agregar labela un nodo, pero "dentro" del nodo. Algo como esto:

salida deseada

El manual parece indicar que podría ser posible, aunque no se menciona ninguna clave real.

El... punto de anclaje para el nodo de etiqueta... se determina de tal manera que el nodo de etiqueta esté "de espaldas" al borde del nodo principal. El ancla que se elige depende de la posición del punto de borde que se elige y su posición relativa al centro del nodo principal y de si está configurada la opción de transformar forma.En general, la elección debe ser la que usted esperaría, pero es posible que usted mismo tenga que fijar el ancla en situaciones difíciles.(énfasis añadido)

Pero cuando pruebo un ejemplo como este:

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\tikz \node [circle,draw,label={[red,anchor=north]above:X}] {my circle};
\end{document}

No obtengo ningún cambio en la posición del nodo de etiqueta. Todavía está "afuera".

producción real

¿Algunas ideas?

Respuesta1

El problema aquí es que TikZ aplica alguna automatización (es decir, la \tikz@auto@anchormacro) que sobrescribirá su conjunto anchor.

Podemos secuestrar una .codeclave que se aplica al final en el nodo que se usa internamente para la etiqueta (sí, incluso después de nuestra propia configuración red, anchor=north) y que llama a \tikz@auto@anchor:

\tikzset{label anchor/.style={tikz@label@post/.append style={anchor=#1}}}

o dejamos que la macro que hace los cálculos se relaje un poco (no se necesita tecla adicional):

\tikzset{anchor/.append code=\let\tikz@auto@anchor\relax}

Si la clave nueva y mejorada anchorahora se usa de manera más global (digamos \tikz[anchor=<dir>]), también afectará a los nodos (y actualmente hay una manera de recuperarla).

También proporciono una clave inside(incluso puedes usarla dos veces para revertir el efecto).

Código

\documentclass[tikz]{standalone}
\usepackage{etoolbox}
\makeatletter
\tikzset{anchor/.append code=\let\tikz@auto@anchor\relax}
\tikzset{inside/.code=\preto\tikz@auto@anchor{\pgf@x-\pgf@x\pgf@y-\pgf@y}}
\makeatother
\begin{document}
\tikz\node [anchor=west, circle,draw,label={[red, anchor=north]above:X}] {my circle};
\tikz\node [anchor=west, circle,draw,label={[red, inside]below:X}] {my circle};
\end{document}

Producción

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Respuesta2

Aquí hay otro enfoque que aprovecha la append after commandopción. La cuestión es que, al hacer referencia al ancla, \tikzlastnode.centerse podrían añadir, en relación con esa posición, etiquetas.

El nuevo estilo capaz de realizar esta tarea es my label:

\tikzset{my label/.style args={#1:#2}{
  append after command={
    (\tikzlastnode.center) node [#1] {#2}
    }
  }
}

Un mwe:

\documentclass[tikz,png,border=10pt]{standalone}
\usepackage{tikz}
\tikzset{my label/.style args={#1:#2}{
    append after command={
       (\tikzlastnode.center) node [#1] {#2}
    }
  }
}
\begin{document}
\tikz \node [circle,draw,my label={red,above=0.15cm:X}] {my circle};
\tikz \node [circle,draw,my label={red,below=0.15cm:X}] {my circle};
\end{document}

lo que da como resultados:

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

El estilo acepta en un primer argumento cualquier opción de TikZ, por lo que es fácil personalizar los colores y la posición: de hecho, es mejor ajustar un poco el desplazamiento para no superponer el texto.

Si, en cambio, se sabe que la etiqueta siempre debe colocarse debajo del "borde norte", bueno, lo mejor es cambiar el my labelestilo a:

\tikzset{my label/.style args={#1:#2}{
    append after command={
       (\tikzlastnode.north) node [#1] {#2}
    }
  }
}

De tal manera, simplemente configurando:

\tikz\node [circle,draw,my label={red,below:X}] {my circle};

permite alcanzar el objetivo.

Un mwe:

\documentclass[tikz,png,border=10pt]{standalone}
\usepackage{tikz}
\tikzset{my label/.style args={#1:#2}{
    append after command={
       (\tikzlastnode.north) node [#1] {#2}
    }
  }
}
\begin{document}
\begin{tikzpicture}
\node [circle,draw,my label={red,below:X}] {my circle};
\node [circle,draw,my label={red,below=0.15cm:X},xshift=2cm] {my circle};
\end{tikzpicture}
\end{document}

El resultado:

ingrese la descripción de la imagen aquí

Revisión

El método anterior sufre, como se dice en los comentarios, si se debe introducir más de una etiqueta. Pero esto es perfectamente factible si en lugar de introducir nodos, introducimos coordenadas con etiquetas.

El código:

\documentclass[tikz,png,border=10pt]{standalone}
\usepackage{tikz}
\tikzset{my label/.style args={[#1]#2:#3}{
    append after command={
       (\tikzlastnode.center) coordinate[label={[label distance=0.1cm,#1]#2:#3}]
    }
  },
}
\begin{document}
\begin{tikzpicture}
\node [circle,
  draw,
  my label={[red]above:X},
  my label={[green!70!blue]below:Y},
  my label={[blue,yshift=0.3cm]above:Z}] {my circle};
\node [circle,
  draw,
  my label={[blue,yshift=-0.15cm]below:X},
  my label={[green!70!blue]70:Z},
  my label={[orange!80!red]130:Y},
  xshift=2cm] {my circle};
\end{tikzpicture}
\end{document}

El resultado:

ingrese la descripción de la imagen aquí

Aviso: al usar label distancedentro de la definición de la opción, permite que el texto de la etiqueta no se superponga cuando uno simplemente dice:

\tikz\node [circle,draw,my label={[red]below:X}] {my circle};

Respuesta3

También puedes cambiar la etiqueta:

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\tikz \node [circle,draw,label={[red,yshift=-0.5cm]above:X}] {my circle};

\tikz \node [circle,draw,label={[red,label distance=-0.5cm]above:X}] {my circle};
\end{document}

información relacionada