Actualmente estoy intentando generar el siguiente diagrama de Venn:
\usetikzlibrary{shapes,backgrounds}
\usepackage{tikz}
\usepackage{xcolor}
\begin{tikzpicture}[scale=.8, show background rectangle]
\def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
\node (a) at (-2.5cm,2.5cm) {C};
\node (b) at (2.5cm,2.5cm) {B};
\node (c) at (-3.5cm,1.5cm) {N};
\node (d) at (3.5cm,1.5cm) {S};
%~A~B~C~D
\scope
\clip \ellipsea\negating;
\clip \ellipseb\negating;
\clip \ellipsec\negating;
\clip \ellipsed\negating;
\fill[color=black,opacity=0.2] \negating;
\endscope
%ABC~D
\scope
\clip \ellipsea;
\clip \ellipseb;
\clip \ellipsec;
\clip \ellipsed\negating;
\fill[color=black,opacity=0.2] \negating;
\endscope
%AB~CD
\scope
\clip \ellipsea;
\clip \ellipseb;
\clip \ellipsec\negating;
\clip \ellipsed;
\fill[color=black,opacity=0.2] \negating;
\endscope
%A~BCD
\scope
\clip \ellipsea;
\clip \ellipseb\negating;
\clip \ellipsec;
\clip \ellipsed;
\fill[color=black,opacity=0.2] \negating;
\endscope
%~ABCD
\scope
\clip \ellipsea\negating;
\clip \ellipseb;
\clip \ellipsec;
\clip \ellipsed;
\fill[color=blue,opacity=0.2] \negating;
\endscope
%ABCD
\scope
\clip \ellipsea;
\clip \ellipseb;
\clip \ellipsec;
\clip \ellipsed;
\fill[color=black,opacity=0.2] \negating;
\endscope
%AB~C~D
\scope
\clip \ellipsea;
\clip \ellipseb;
\clip \ellipsec\negating;
\clip \ellipsed\negating;
\fill[color=green,opacity=0.2] \negating;
\endscope
%A~B~CD
\scope
\clip \ellipsea;
\clip \ellipseb\negating;
\clip \ellipsec\negating;
\clip \ellipsed;
\fill[color=yellow,opacity=0.2] \negating;
\endscope
%~AB~CD
\scope
\clip \ellipsea\negating;
\clip \ellipseb;
\clip \ellipsec\negating;
\clip \ellipsed;
\fill[color=black,opacity=0.2] \negating;
\endscope
%~ABC~D
\scope
\clip \ellipsea\negating;
\clip \ellipseb;
\clip \ellipsec;
\clip \ellipsed\negating;
\fill[color=red,opacity=0.2] \negating;
\endscope
%~A~BCD
\scope
\clip \ellipsea\negating;
\clip \ellipseb\negating;
\clip \ellipsec;
\clip \ellipsed;
\fill[color=orange,opacity=0.2] \negating;
\endscope
%~AB~C~D
\scope
\clip \ellipsea\negating;
\clip \ellipseb;
\clip \ellipsec\negating;
\clip \ellipsed\negating;
\fill[color=black,opacity=0.2] \negating;
\endscope
%~A~B~CD
\scope
\clip \ellipsea\negating;
\clip \ellipseb\negating;
\clip \ellipsec\negating;
\clip \ellipsed;
\fill[color=purple,opacity=0.2] \negating;
\endscope
%A~B~D
\scope
\clip \ellipsea;
\clip \ellipseb\negating;
\clip \ellipsed\negating;
\fill[color=red,opacity=0.5] \negating;
\endscope
%~BC~D
\scope
\clip \ellipseb\negating;
\clip \ellipsec;
\clip \ellipsed\negating;
\fill[color=blue,opacity=0.5] \negating;
\endscope
\node (ABcd) at (0,1cm) {1};
\node (aBCD) at (0.5cm,-2.25cm) {1};
\node (AbcD) at (-1.2cm,-1.9cm) {1};
\node (aBCd) at (1.2cm,-1.9cm) {2};
\node (abCD) at (0,-3cm) {4};
\node (abcD) at (-3cm,0cm) {1};
\node (Abd) at (1.8cm,1.1cm) {3};
\node (bCd) at (2.5cm,.5cm) {4};
\draw \ellipsea;
\draw \ellipseb;
\draw \ellipsec;
\draw \ellipsed;
\end{tikzpicture}
usando el bucle tikz \foreach, para mayor claridad, así:
\foreach \abool/\bbool/\cbool/\dbool/\colchoose/\opchoose in {1/1/1/1,black,0.2}
\scope
\ifnum \abool=1
\clip \ellipsea;
[\else \clip \ellipsea\negating;]
\fi
\ifnum \bbool=1
\clip \ellipseb;
[\else \clip \ellipseb\negating;]
\fi
\ifnum \cbool=1
\clip \ellipsec;
[\else \clip \ellipsec\negating;]
\fi
\ifnum \dbool=1
\clip \ellipsed;
[\else \clip \ellipsed\negating;]
\fi
\fill[color=\colchoose,opacity=\opchoose] \negating;
\endscope
Para reemplazar la larga línea de \scope s en la pieza original. Esto parece funcionar bien, hasta que agrego varias áreas (como {1/1/1/1/black/0.2,0/1/0/1,black,0.2}), en cuyo caso aparece el siguiente error:
! Missing } inserted.<inserted text>} \end{tikzpicture}
! Missing \endgroup inserted.<inserted text>\endgroup \end{document}
Me preguntaba cómo solucionar este problema o si hay algún problema con mi código, ya que soy bastante nuevo en tikz.
¡Gracias!
Respuesta1
Tu código funciona bien si
Hay que tener cuidado con los valores del
\foreach
bucle: los valores de varias variables de una iteración deben estar separados por/
, los valores de diferentes iteraciones por,
.\foreach ... in {1/1/1/1/black/0.2,0/1/0/1/black/0.2}
(En su lugar, lo intentaste
{1/1/1/1/black/0.2,0/1/0/1,black,0.2}
).Encierre el cuerpo del bucle entre tirantes.
\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds}
%\usepackage{xcolor}
\begin{document}
\begin{tikzpicture}[scale=.8, show background rectangle]
\def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
\node (a) at (-2.5cm,2.5cm) {C};
\node (b) at (2.5cm,2.5cm) {B};
\node (c) at (-3.5cm,1.5cm) {N};
\node (d) at (3.5cm,1.5cm) {S};
\foreach \abool/\bbool/\cbool/\dbool/\colchoose/\opchoose in {1/1/1/1/black/0.2,0/1/0/1/black/0.2}
{ \scope
\ifnum \abool=1
\clip \ellipsea;
[\else \clip \ellipsea\negating;]
\fi
\ifnum \bbool=1
\clip \ellipseb;
[\else \clip \ellipseb\negating;]
\fi
\ifnum \cbool=1
\clip \ellipsec;
[\else \clip \ellipsec\negating;]
\fi
\ifnum \dbool=1
\clip \ellipsed;
[\else \clip \ellipsed\negating;]
\fi
\fill[color=\colchoose,opacity=\opchoose] \negating;
\endscope
}
\node (ABcd) at (0,1cm) {1};
\node (aBCD) at (0.5cm,-2.25cm) {1};
\node (AbcD) at (-1.2cm,-1.9cm) {1};
\node (aBCd) at (1.2cm,-1.9cm) {2};
\node (abCD) at (0,-3cm) {4};
\node (abcD) at (-3cm,0cm) {1};
\node (Abd) at (1.8cm,1.1cm) {3};
\node (bCd) at (2.5cm,.5cm) {4};
\draw \ellipsea;
\draw \ellipseb;
\draw \ellipsec;
\draw \ellipsed;
\end{tikzpicture}
\end{document}
Respuesta2
En realidad, estoy ignorando principalmente la pregunta de los OP y proporcionando una forma más eficiente de especificar el diagrama:
\documentclass[tikz,border=5]{standalone}
\tikzset{%
venn/.code 2 args={\scope\def\c{#1}\def\n{}\tikzset{.. venn=#2@;}\endscope},
.. venn/.code args={#1#2;}{%
\ifx#1@%
\path[fill=\c]\negating;
\else%
\ifx#1~
\let\n=\negating
\else%
\clip \csname ellipse#1\endcsname\n;
\def\n{}%
\fi%
\tikzset{.. venn=#2;}%
\fi}}
\def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
\newcommand\venn[2][]{\tikzset{venn={#1}{#2}}}
\begin{document}
\begin{tikzpicture}
\venn [red] {abcd}
\venn [yellow] {~abcd}
\venn [pink] {a~bcd}
\venn [green] {ab~cd}
\venn [orange] {abc~d}
\venn [purple] {~a~bcd}
\venn [blue] {~ab~cd}
\venn [magenta] {~abc~d}
\venn [olive] {a~b~cd}
\venn [violet] {a~bc~d}
\venn [teal] {ab~c~d}
\venn [brown] {~a~b~cd}
\venn [teal] {~a~bc~d}
\venn [lime] {~ab~c~d}
\venn [darkgray] {a~b~c~d}
\venn [lightgray] {~a~b~c~d}
\end{tikzpicture}
\end{document}
Y aquí hay una variante que (a) todavía no responde a la pregunta de los OP pero (b) permite la especificación como una secuencia de bits, por ejemplo 1101
:
\documentclass[tikz,border=5]{standalone}
\tikzset{%
venn/.code 2 args={\scope\def\c{#1}\tikzset{.. venn/.expanded=#2@;abcd@;}\endscope},
.. venn/.code args={#1#2;#3#4;}{%
\ifx#1@%
\path[fill=\c]\negating;
\else%
\ifcase#1
\clip \csname ellipse#3\endcsname\negating;
\or%
\clip \csname ellipse#3\endcsname;
\fi%
\tikzset{.. venn=#2;#4;}%
\fi%
}}
\def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
\newcommand\venn[2][]{\tikzset{venn={#1}{#2}}}
\pgfmathsetbasenumberlength{4}
\begin{document}
\begin{tikzpicture}
\foreach \i [evaluate={\r=rnd;\g=rnd;\b=rnd;}] in {0,...,15}{
\definecolor{tmp}{rgb}{\r,\g,\b}
\pgfmathdectobase\n{\i}{2}%
\venn[tmp]{\n}
}
\end{tikzpicture}
\end{document}
La acción del 'analizador' (es decir, las teclas venn
y venn ..
) quizás pueda explicarse mejor con un ejemplo.
Considere lo que sucede cuando se usa \venn{1100}
.
La venn
llave 'llama' .. venn=1100@;abcd@;
. Son abcd
los sufijos de los comandos \ellipsea
, y \ellipseb
. Los caracteres son caracteres centinela (arbitrarios) que permiten detectar cuándo se ha llegado al final de una secuencia. Los caracteres son delineadores para marcar el final de las cadenas. Luego considere cada iteración por turno:\ellipsec
\ellipsed
@
;
Los argumentos de la
.. venn
clave son#1 -> 1 #2 -> 100@ #3 -> a #4 -> bcd@
Los argumentos de la
.. venn
clave son#1 -> 1 #2 -> 00@ #3 -> b #4 -> cd@
Los argumentos de la
.. venn
clave son#1 -> 0 #2 -> 0@ #3 -> c #4 -> d@
Los argumentos de la
.. venn
clave son#1 -> 0 #2 -> @ #3 -> d #4 -> @
Los argumentos de la
.. venn
clave son#1 -> @ #2 -> #3 -> @ #4 ->
Al alcanzar el carácter centinela, el analizador finaliza.