如何使用图表下的数据扩展 tikzpicture?

如何使用图表下的数据扩展 tikzpicture?

如何使用图表下的数据扩展 tikzpicture?

我写了下面的图表,在 LaTeX 中显示得很好。但是,图中的点非常接近,因此很难看出哪个图点高于另一个。

在此处输入图片描述

我需要的是一张表格,图表下方有数据,就像我在 Excel 中做的那样。如何在 LaTeX 中做到这一点?

在此处输入图片描述

\begin{figure}[htbp]
\centering
\begin{tikzpicture}
\begin{axis}[
    title={\textbf{All-Pairs Shortest Path}},
    scaled y ticks = false,
    y tick label style={/pgf/number format/fixed,
    /pgf/number format/1000 sep = \thinspace},
    xlabel={Matrix Dimension},
    ylabel={Gas},
    xmin=0, xmax=25,
    ymin=0, ymax=10500000,
    xtick={1,4,8,12,16,20,24},
    %ytick={},
    legend pos=north west,
    ymajorgrids=true,
    grid style=dashed,
    width = \linewidth
]

\addplot[
    color=blue,
    mark=*,
    mark options={scale=1.50}
    ]
    coordinates {
    (1,23902)(4,78508)(8,426081)(12,1338366)(16,3086445)(20,5945874)(24,10182149)
    };

\addplot[
    color=red,
    mark=triangle*,
    mark options={scale=1.50},
    ]
    coordinates {
    (1,107391)(4,154467)(8,306647)(12,563926)(16,928604)(20,1411996)(24,2025096)
    };
    \legend{Local, Oraclize}    

\end{axis}
\end{tikzpicture}
\caption{Gas cost of computing all-pairs shortest path (APSP) using Floyd-Warshall algorithm. (Source: Project)}
\label{fig:apsp}
\end{figure}

如果我使用 Torbjørn 的答案来绘制包含 10 个数据点的图表,

\pgfplotsset{compat=1.14}
% read in data
\pgfplotstableread{
x v nv
1 22147 107477
5 26844 120709
10 32674 137975
25 60060 188721
50 101523 274672
100 205331 445946
250 542985 982947
500 1208542 1914372
750 1956327 2901016
1000 2634826 3928101
}\datatable

% get number of rows
\pgfplotstablegetrowsof{\datatable}
% subtract 1 because table indices start at 0
\pgfmathsetmacro{\Nrows}{\pgfplotsretval-1}
% for convenience, macro to store width of axis
\pgfmathsetlengthmacro{\MyAxisW}{10cm}

\begin{figure}[htbp]
\centering
\begin{tikzpicture}[
  cell/.style={ % style used for "table" cells
    draw,
    minimum width={\MyAxisW/(\Nrows+1)}, % +1 because -1 above
    minimum height=4ex,
    inner sep=0pt,
    outer sep=0pt,
    anchor=north west,
    font=\sffamily\scriptsize
  }]
\begin{axis}[
   name=ax,
   % so axis labels and ticklabels are not accounted for in size settings   
   scale only axis,
   width=\MyAxisW,
   height=4cm,
   % we add the ticklabels as part of the table, so no xticks needed
   xtick=\empty,
   % and add grid lines
   grid=major,
   % only need left y-axis line
   axis y line=left,
   x axis line style={draw=none},
   % and for that we need to make sure that the distance from the first/last tick
   % to the axis edge is the same, so that there is a half a bar width of space
   enlarge x limits={abs={\MyAxisW/(2*\Nrows+2)}},
   ymin=0,
   title={Array Sorting},
   title style={font=\bfseries},
   ylabel={Gas},
   xlabel={\# matrix dimension},
   % move xlabel to below table
   xlabel shift=12ex,
   % set yticks as sans serif
   tick label style={
    font=\sansmath\sffamily\small,
    % and remove comma in 1,000
    /pgf/number format/set thousands separator=},
   % set axis labels as sans serif
   label style={font=\sansmath\sffamily}
  ]
  % because the x-values are not evenly spaced, used index as x-value instead
  \addplot +[black!60] table[x expr=\coordindex,y=nv] {\datatable};
  \label{dataNV}

  \addplot +[black!20] table[x expr=\coordindex,y=v] {\datatable};
  \label{dataV}
\end{axis}

% define a starter coordinate at the lower left corner of the axis
\coordinate (c-0-0) at (ax.south west);

% loop over the table
\foreach [count=\j from 1] \i in {0,...,\Nrows}
  {
  % get element \i from the x-column, stored in \pgfplotsretval
  \pgfplotstablegetelem{\i}{x}\of\datatable
  % add node with value
  \node [cell] (c-0-\j) at (c-0-\i.north east) {\pgfplotsretval};
  % repeat for other two columns
  \pgfplotstablegetelem{\i}{v}\of\datatable
  \node [cell] (c-1-\j) at (c-0-\j.south west) {\pgfplotsretval};
  \pgfplotstablegetelem{\i}{nv}\of\datatable
  \node [cell] (c-2-\j) at (c-1-\j.south west) {\pgfplotsretval};
  }

% add "legend" on the left
\matrix [draw,nodes={cell,minimum width=0pt,draw=none},anchor=north east,row sep=0pt,column sep=5pt,outer sep=0pt,inner ysep=0pt] (m) at (c-1-1.north west)
{
 \node {\ref{dataV}};  & \node{Gas: Oraclize}; \\
 \node {\ref{dataNV}}; & \node{Gas: local}; \\
};

% draw center line of legend
\draw (m.west) -- (m.east);

\end{tikzpicture}
\end{figure}

在此处输入图片描述

我遇到的问题是关于 x 轴上的“点”(数据点)以及对于数据来说太小的列?

答案1

接受代码表格上方的堆叠条形图,并做以下几件事:

  • 用您的数据替换其中\pgfplotstableread的数据。第一列为 x 值,然后两列为 y 数据。
  • 从选项中删除axis
    • ybar stacked(不需要条形图)
    • bar width={...}(不需要,不是条形图)
    • ytick distance=200(当 y 轴跨度达到 10^7 时就太荒谬了)
  • 在选项中更改ylabel/ ,并添加。xlabelaxistitle
  • \matrix在生成图例 的选项中:
    • 改成nodes={cell,draw=none}nodes={cell,minimum width=0pt,draw=none}
    • column sep=5pt在 旁边添加row sep
  • +[black!60]从第一个\addplot+[black!20]第二个中删除。

如果数字对于单元格来说太宽,您可以采取以下几种措施。

  • 将样式中\scriptstyle的改为,以减小字体大小。即,您将在下面找到,将其改为。\tinycellfont=\sffamily\scriptsizefont=\sffamily\tiny
  • 增加轴的宽度。宽度在\MyAxisW宏中定义,因此从 更改为\pgfmathsetlengthmacro{\MyAxisW}{10cm}例如\pgfmathsetlengthmacro{\MyAxisW}{12cm}

或者两者都做,这取决于数字、数据点的数量等。

由于ymin=0,数字最小的点位于 x 轴上。要解决这个问题,您可以做以下两件事之一:

  • ymin例如,将值更改为ymin=-1e5
  • ymin=0用。。。来代替enlarge y limits

要添加第三个图,您需要

  • 在表中添加新列
  • 添加新的\addplot
  • 假设新列nnv名为

    \pgfplotstablegetelem{\i}{nnv}\of\datatable
    \node [cell] (c-3-\j) at (c-2-\j.south west) {\pgfplotsretval};
    

    到构建表的循环

  • 修改图例中水平线的绘制方法
  • 增加xlabel shift, 以解释新的表格行

代码输出

\documentclass[border=5mm]{standalone}

% for sans serif ticks (https://tex.stackexchange.com/questions/33325/)
\usepackage[eulergreek]{sansmath}

\usepackage{pgfplots,pgfplotstable}
\pgfplotsset{compat=1.14}
% read in data
\pgfplotstableread{
x v nv nnv
1 23902 107391 100391
4 78508 154467 254467
8 426081 306647 406647
12 1338366 563926 550926
16 3086445 928604 1028604
20 5945874 1411996 1511996
24 10182149 2025096 2525096
}\datatable

% get number of rows
\pgfplotstablegetrowsof{\datatable}
% subtract 1 because table indices start at 0
\pgfmathsetmacro{\Nrows}{\pgfplotsretval-1}
% for convenience, macro to store width of axis
\pgfmathsetlengthmacro{\MyAxisW}{10cm}

\begin{document}%
\begin{tikzpicture}[
  cell/.style={ % style used for "table" cells
    draw,
    minimum width={\MyAxisW/(\Nrows+1)}, % +1 because -1 above
    minimum height=4ex,
    inner sep=0pt,
    outer sep=0pt,
    anchor=north west,
    font=\sffamily\scriptsize
  }]
\begin{axis}[
   name=ax,
   % so axis labels and ticklabels are not accounted for in size settings   
   scale only axis,
   width=\MyAxisW,
   height=4cm,
   % we add the ticklabels as part of the table, so no xticks needed
   xtick=\empty,
   % and add grid lines
   grid=major,
   % only need left y-axis line
   axis y line=left,
   x axis line style={draw=none},
   % and for that we need to make sure that the distance from the first/last tick
   % to the axis edge is the same, so that there is a half a bar width of space
   enlarge x limits={abs={\MyAxisW/(2*\Nrows+2)}},
   ymin=0,
   title={All-Pairs Shortest Path},
   title style={font=\bfseries},
   ylabel={Gas},
   xlabel={\# matrix dimension},
   % move xlabel to below table
   xlabel shift=16ex,
   % set yticks as sans serif
   tick label style={
    font=\sansmath\sffamily\small,
    % and remove comma in 1,000
    /pgf/number format/set thousands separator=},
   % set axis labels as sans serif
   label style={font=\sansmath\sffamily}
  ]
  % because the x-values are not evenly spaced, used index as x-value instead
  \addplot table[x expr=\coordindex,y=nnv] {\datatable};
  \label{dataNNV}

  \addplot table[x expr=\coordindex,y=nv] {\datatable};
  \label{dataNV}

  \addplot table[x expr=\coordindex,y=v] {\datatable};
  \label{dataV}
\end{axis}

% define a starter coordinate at the lower left corner of the axis
\coordinate (c-0-0) at (ax.south west);

% loop over the table
\foreach [count=\j from 1] \i in {0,...,\Nrows}
  {
  % get element \i from the x-column, stored in \pgfplotsretval
  \pgfplotstablegetelem{\i}{x}\of\datatable
  % add node with value
  \node [cell] (c-0-\j) at (c-0-\i.north east) {\pgfplotsretval};
  % repeat for other two columns
  \pgfplotstablegetelem{\i}{v}\of\datatable
  \node [cell] (c-1-\j) at (c-0-\j.south west) {\pgfplotsretval};
  \pgfplotstablegetelem{\i}{nv}\of\datatable
  \node [cell] (c-2-\j) at (c-1-\j.south west) {\pgfplotsretval};
  \pgfplotstablegetelem{\i}{nnv}\of\datatable
  \node [cell] (c-3-\j) at (c-2-\j.south west) {\pgfplotsretval};
  }

% add "legend" on the left
\matrix [draw,nodes={cell,minimum width=0pt,draw=none},anchor=north east,row sep=0pt,column sep=5pt,outer sep=0pt,inner ysep=0pt] (m) at (c-1-1.north west)
{
 \node {\ref{dataV}};  & \node{Gas: Oraclize}; \\
 \node {\ref{dataNV}}; & \node{Gas: local}; \\
 \node {\ref{dataNNV}}; & \node{Foobar}; \\
};

% draw horizontal lines in legend
\draw (m.west |- c-1-1.south west) -- (c-1-1.south west);
\draw (m.west |- c-2-1.south west) -- (c-2-1.south west);


\end{tikzpicture}
\end{document}

相关内容