我目前正在嘗試生成以下維恩圖:
\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}
為了清楚起見,使用 tikz \foreach 循環,如下所示:
\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
替換原始片段中的長行 \scope 。這似乎工作正常,直到我添加多個區域(例如{1/1/1/1/black/0.2,0/1/0/1,black,0.2}),在這種情況下,我收到以下錯誤:
! Missing } inserted.<inserted text>} \end{tikzpicture}
! Missing \endgroup inserted.<inserted text>\endgroup \end{document}
想知道如何解決這個問題,或者我的程式碼是否有問題,因為我對 tikz 還很陌生。
謝謝!
答案1
如果你的程式碼工作正常
您對循環的值要小心
\foreach
:一次迭代的多個變數的值必須以 分隔/
,不同迭代的值必須以分隔,
。\foreach ... in {1/1/1/1/black/0.2,0/1/0/1/black/0.2}
(你嘗試過
{1/1/1/1/black/0.2,0/1/0/1,black,0.2}
。)將循環體用大括號括起來。
\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}
答案2
實際上,我基本上忽略了OP問題並提供了一種更有效的指定圖表的方法:
\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}
這是一個變體,它 (a) 仍然不能回答 OP 問題,但 (b) 可以將規範指定為位元序列,例如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}
「解析器」(即venn
和venn ..
鍵)的操作也許可以用一個例子來最好地解釋。
考慮使用時會發生什麼\venn{1100}
。
關鍵venn
是‘呼叫’ .. venn=1100@;abcd@;
。是、、和命令abcd
的後綴。這些字符是(任意)哨兵字符,可以檢測何時到達序列末尾。這些字元是標記字串末尾的輪廓符。然後依序考慮每次迭代:\ellipsea
\ellipseb
\ellipsec
\ellipsed
@
;
鍵的參數
.. venn
是#1 -> 1 #2 -> 100@ #3 -> a #4 -> bcd@
鍵的參數
.. venn
是#1 -> 1 #2 -> 00@ #3 -> b #4 -> cd@
鍵的參數
.. venn
是#1 -> 0 #2 -> 0@ #3 -> c #4 -> d@
鍵的參數
.. venn
是#1 -> 0 #2 -> @ #3 -> d #4 -> @
鍵的參數
.. venn
是#1 -> @ #2 -> #3 -> @ #4 ->
到達哨兵字元後,解析器終止。