我需要制作一个与另一篇论文中的图表相似的图表。实现此目的的最简单方法是什么?。
到目前为止,我已经弄清楚了如何使用 TikZ 绘制椭圆,但我找不到让间距看起来正确的方法。
\newcommand{\A}{\tikz \draw (0,0) circle [x radius=3pt, y radius=6pt ];}
\newcommand{\B}{\tikz \filldraw (0,0) circle [x radius=3pt, y radius=6pt ];}
\newcommand{\ovals}[2]{\parbox{25pt}{\centering#1\\#2}}
\begin{center}
\ovals{\B\B}{0.05} \\
\ovals{\A\B}{0.10} \ovals{\B\A}{0.20} \\
\ovals{\A\A}{1.00} \\
\end{center}
对于 N=2,这是我目前能得到的最佳结果:
- 如何减少椭圆和其下方相关数字之间的垂直空间?
- 如何增加数字底部和其下方椭圆行之间的垂直空间?
答案1
如果您已经加载 Ti钾Z 那么你可以将它用于所有方面。你的问题可以使用解析器模块、图片和矩阵来解决。这个答案定义了一个图片,,ovals
其参数的第一部分可以是一系列*
和o
,它们转换成椭圆。
该表可以用矩阵来完成。
代码很简单
\begin{tikzpicture}[column sep=1ex]
\path (0,0) node[matrix]{\pic{ovals={******/0.7}};\\}
(0,-1) node[matrix]{\pic{ovals={o*****/103.4}}; &
\pic{ovals={*o****/81.5}}; & \pic{ovals={**o***/1.7}};
& \pic{ovals={***o**/0.7}}; & \pic{ovals={****o*/11.4}};
& \pic{ovals={*****o/3.3}};\\};
\end{tikzpicture}
完整文档及其定义pic
:
\documentclass{article}
\usepackage{tikz}
\usepgfmodule{parser}
\newcounter{oval}
\newif\ifdrawovals
\pgfparserdef{ovalparser}{initial}{the letter o}%
{\ifdrawovals
\draw (\ovalshift*1pt+\number\value{oval}*6pt,6pt) circle [x radius=3pt, y radius=6pt ];
\fi
\stepcounter{oval}}%
\pgfparserdef{ovalparser}{initial}{the character *}%
{\ifdrawovals
\draw[fill] (\ovalshift*1pt+\number\value{oval}*6pt,6pt) circle [x radius=3pt, y radius=6pt ];
\fi
\stepcounter{oval}}%
\pgfparserdef{ovalparser}{initial}{the character ;}%
{\pgfparserswitch{final}}
\pgfmathtruncatemacro\ovalshift{0}
\tikzset{pics/ovals/.style args={#1/#2}{code={
\setcounter{oval}{0}
\drawovalsfalse
\pgfparserparse{ovalparser}#1;
\pgfmathtruncatemacro\ovalshift{3-3*\number\value{oval}}
\setcounter{oval}{0}
\drawovalstrue
\pgfparserparse{ovalparser}#1;
\path (0,0) node[below]{#2x};
}},pics/ovals/.default=o/{}}
\begin{document}
For instance,
\begin{quote}
\verb|\pic{ovals={**o*o*/1.4}};|
\end{quote}
inside a \verb|tikzpicture| environment yields
\begin{quote}
\tikz{\pic{ovals={**o*o*/1.4}};}
\end{quote}
You can use stack matrices to produce your table, you will have perfect control
over all aspect. The \verb|column sep| controls the horizontal space between the
cells, the vertical distance is controlled by the coordinate in fron of the
matrix node. This is a start.
\begin{center}
\begin{tikzpicture}[column sep=1ex]
\path (0,0) node[matrix]{\pic{ovals={******/0.7}};\\}
(0,-1) node[matrix]{\pic{ovals={o*****/103.4}}; &
\pic{ovals={*o****/81.5}}; & \pic{ovals={**o***/1.7}};
& \pic{ovals={***o**/0.7}}; & \pic{ovals={****o*/11.4}};
& \pic{ovals={*****o/3.3}};\\};
\end{tikzpicture}
\end{center}
\end{document}
当然,如果有一个公式可以从已填充和空索引的二进制代码中得出 x 前面的数字,那么整个表格就可以通过编程完成。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{etoolbox}
\usepackage{tikz}
\tikzset{pics/ovals/.style args={#1/#2}{code={
\foreach \XX [count=\YY] in {#1}
{\draw (-21pt+\YY*6pt,6pt) \ifnum\XX=1 [fill] \fi circle[x radius=3pt,y radius=6pt];]}
\path (0,0) node[below]{\pgfmathprintnumber{#2}x};
}},pics/ovals/.default=o/{}}
\begin{document}
\begin{tikzpicture}[column sep=1ex,ampersand replacement=\&]
\def\mylst{{{0, 0, 0, 0, 0, 0}}, {{0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 0}, {0, 0,
0, 1, 0, 0}, {0, 0, 1, 0, 0, 0}, {0, 1, 0, 0, 0, 0}, {1, 0, 0, 0,
0, 0}}, {{0, 0, 0, 0, 1, 1}, {0, 0, 0, 1, 0, 1}, {0, 0, 0, 1, 1,
0}, {0, 0, 1, 0, 0, 1}, {0, 0, 1, 0, 1, 0}, {0, 0, 1, 1, 0, 0}, {0,
1, 0, 0, 0, 1}, {0, 1, 0, 0, 1, 0}, {0, 1, 0, 1, 0, 0}, {0, 1, 1,
0, 0, 0}, {1, 0, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0}, {1, 0, 0, 1, 0,
0}, {1, 0, 1, 0, 0, 0}, {1, 1, 0, 0, 0, 0}}, {{0, 0, 0, 1, 1,
1}, {0, 0, 1, 0, 1, 1}, {0, 0, 1, 1, 0, 1}, {0, 0, 1, 1, 1, 0}, {0,
1, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 1}, {0, 1, 0, 1, 1, 0}, {0, 1, 1,
0, 0, 1}, {0, 1, 1, 0, 1, 0}, {0, 1, 1, 1, 0, 0}, {1, 0, 0, 0, 1,
1}, {1, 0, 0, 1, 0, 1}, {1, 0, 0, 1, 1, 0}, {1, 0, 1, 0, 0, 1}, {1,
0, 1, 0, 1, 0}, {1, 0, 1, 1, 0, 0}, {1, 1, 0, 0, 0, 1}, {1, 1, 0,
0, 1, 0}, {1, 1, 0, 1, 0, 0}, {1, 1, 1, 0, 0, 0}}, {{0, 0, 1, 1, 1,
1}, {0, 1, 0, 1, 1, 1}, {0, 1, 1, 0, 1, 1}, {0, 1, 1, 1, 0,
1}, {0, 1, 1, 1, 1, 0}, {1, 0, 0, 1, 1, 1}, {1, 0, 1, 0, 1, 1}, {1,
0, 1, 1, 0, 1}, {1, 0, 1, 1, 1, 0}, {1, 1, 0, 0, 1, 1}, {1, 1, 0,
1, 0, 1}, {1, 1, 0, 1, 1, 0}, {1, 1, 1, 0, 0, 1}, {1, 1, 1, 0, 1,
0}, {1, 1, 1, 1, 0, 0}}, {{0, 1, 1, 1, 1, 1}, {1, 0, 1, 1, 1,
1}, {1, 1, 0, 1, 1, 1}, {1, 1, 1, 0, 1, 1}, {1, 1, 1, 1, 0, 1}, {1,
1, 1, 1, 1, 0}}, {{1, 1, 1, 1, 1, 1}}}
\foreach \Lst [count=\Y] in \mylst
{\let\myrow\empty
\foreach \Bin [count=\Z] in \Lst
{\pgfmathsetmacro{\myrnd}{int(100*rnd+50)/100}\begingroup\edef\tmp{\endgroup
\noexpand\gappto\noexpand\myrow{\noexpand\pic{ovals={\Bin/\myrnd}}; \&}}\tmp
}
\gappto\myrow{\\}
\path (0,\Y) node[matrix]{\myrow};
}
\end{tikzpicture}
\end{document}
答案2
我将使用tabular
来堆叠椭圆和标签。
还提供了使用二进制字符串的椭圆的更简单的输入。
\documentclass{article}
\usepackage{tikz,xparse}
\newcommand{\emptyoval}{\tikz \draw (0,0) circle [x radius=3pt, y radius=6pt ];}
\newcommand{\filledoval}{\tikz \filldraw (0,0) circle [x radius=3pt, y radius=6pt ];}
\newcommand{\ovals}[2]{%
\begin{tabular}{@{}c@{}}\makeovals{#1}\\#2\end{tabular}%
}
\ExplSyntaxOn
\NewDocumentCommand{\makeovals}{m}
{
\str_map_inline:nn { #1 }
{
\str_case:nn { ##1 }
{
{0}{\emptyoval}
{1}{\filledoval}
}
}
}
\ExplSyntaxOff
\begin{document}
\begin{center}
\ovals{11}{0.05} \\[1ex]
\ovals{01}{0.10} \ovals{10}{0.20} \\[1ex]
\ovals{00}{1.00}
\end{center}
\end{document}
一个具有更友好的输入语法的版本,还展示了如何挤压大图(但如果可以的话,请避免这样做)。行之间的额外空间可以通过可选参数进行自定义(在了解挤压操作后使用它)。
\documentclass{article}
\usepackage{tikz,xparse,varwidth,graphicx}
\newsavebox{\emptyoval}\newsavebox{\filledoval}
\sbox{\emptyoval}{\tikz \draw (0,0) circle [x radius=3pt, y radius=6pt ];}
\sbox{\filledoval}{\tikz \filldraw (0,0) circle [x radius=3pt, y radius=6pt ];}
\ExplSyntaxOn
\NewDocumentCommand{\ovals}{O{1ex}m}
{
\seq_set_split:Nnn \l_hugomg_ovals_rows_seq { \\ } { #2 }
\seq_pop_right:NN \l_hugomg_ovals_rows_seq \l_hugomg_ovals_lastrow_tl
\seq_map_inline:Nn \l_hugomg_ovals_rows_seq
{
\hugomg_ovals_row:n { ##1 } \\[#1]
}
\hugomg_ovals_row:V \l_hugomg_ovals_lastrow_tl
}
\cs_new_protected:Nn \hugomg_ovals_row:n
{
\clist_map_function:nN { #1 } \hugomg_ovals_entry:n
}
\cs_generate_variant:Nn \hugomg_ovals_row:n { V }
\cs_new_protected:Nn \hugomg_ovals_entry:n
{
\hugomg_ovals_entry:w #1 \q_nil
}
\cs_new_protected:Npn \hugomg_ovals_entry:w #1 / #2 \q_nil
{
\begin{tabular}[b]{c}\hugomg_ovals_make:n {#1} \\ #2 \end{tabular}
}
\cs_new_protected:Nn \hugomg_ovals_make:n
{
\str_map_inline:nn { #1 }
{
\str_case:nn { ##1 }
{
{0}{\usebox{\emptyoval}}
{1}{\usebox{\filledoval}}
}
}
}
\ExplSyntaxOff
\begin{document}
\begin{center}
\ovals{
11/0.05x \\
01/0.10x, 10/0.20x \\
00/1.00x
}
\end{center}
\noindent
\resizebox{\textwidth}{!}{%
\begin{varwidth}{4\textwidth}
\centering
\ovals[3ex]{
111111/0.7x
\\
011111/103.4x, 101111/81.5x, 110111/1.7x, 111011/11.4x, 111110/3.3x
\\
001111/44.1x, 010111/99.2x, 011011/100.8x, 011101/93.9x, 011110/105.3x,
100111/81.9x, 101011/81.9x, 101101/77.5x, 101110/82.7x,
110011/1.8x, 110101/12.1x, 110110/4.3x,
111001/11.2x, 111010/3.3x, 111100/10.3x,
}
\end{varwidth}%
}
\end{document}
答案3
使用和的可能性tabular
:cellspace
stackengine
\documentclass{article}
\usepackage{tikz}
\usepackage[usestackEOL]{stackengine}
\usepackage{cellspace}
\setlength{\cellspacetoplimit}{5pt}
\setlength{\cellspacebottomlimit}{5pt}
\newcommand{\A}{\tikz \draw (0,0) circle [x radius=3pt, y radius=6pt ];}
\newcommand{\B}{\tikz \filldraw (0,0) circle [x radius=3pt, y radius=6pt ];}
\newcommand{\ovals}[2]{\setstackgap{S}{2pt}\Shortstack{#1\\#2}}
\begin{document}
\begin{center}
\begin{tabular}{Sc}
\ovals{\B\B}{0.05} \\
\ovals{\A\B}{0.10}\quad\ovals{\B\A}{0.20} \\
\ovals{\A\A}{1.00}
\end{tabular}
\end{center}
\end{document}