\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
0 59 29
0.01 40 70
0.02 53 81
0.03 60 83
0.04 76 82
0.05 78 86
0.10 119 88
0.20 210 89
0.30 376 89
0.40 508 90
0.50 605 91
0.60 654 91
0.70 705 91
0.80 766 91
0.90 856 91
1.00 1026 91
}\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,
% use a stacked bar char
ybar stacked,
% we add the ticklabels as part of the table, so no xticks needed
xtick=\empty,
% set distance between yticks
ytick distance=200,
% and add grid lines
grid=major,
% only need left y-axis line
axis y line=left,
x axis line style={draw=none},
% divide axis width by twice the number of rows, so that the whitespace between
% bars is the same as the bar width ...
bar width={\MyAxisW/(2*\Nrows+2)},
% 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,
ylabel={Number of interactions},
xlabel={$p$-value},
% 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,draw=none},anchor=north east,row sep=0pt,outer sep=0pt,inner ysep=0pt] (m) at (c-1-1.north west)
{
\node {\ref{dataV}}; & \node{Non-validated}; \\
\node {\ref{dataNV}}; & \node{Validated}; \\
};
% draw center line of legend
\draw (m.west) -- (m.east);
\end{tikzpicture}
\end{document}
如何去掉10cm的固定宽度,同时又不影响整体形状的美观?
答案1
\pgfmathsetlengthmacro{\MyAxisW}{10cm}
已移除。其中,
axis
所有对 的引用\MyAxisW
都被 替换为\pgfkeysvalueof{/pgfplots/width}
。在之后
axis
,\MyAxisW
则定义为\path (ax.north east); \pgfgetlastxy{\MyAxisW}{\MyAxisH}
(可能存在更好的方法)。样式定义完成后,其定义
cell
下移。\MyAxisW
已width
设置12cm
为作为示例。如果留空width
,则创建的图表太小,表格无法容纳。代码未进行任何其他更改/清理/改进。
\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
0 59 29
0.01 40 70
0.02 53 81
0.03 60 83
0.04 76 82
0.05 78 86
0.10 119 88
0.20 210 89
0.30 376 89
0.40 508 90
0.50 605 91
0.60 654 91
0.70 705 91
0.80 766 91
0.90 856 91
1.00 1026 91
}\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
\begin{document}%
\begin{tikzpicture}[]
\begin{axis}[
name=ax,
% so axis labels and ticklabels are not accounted for in size settings
scale only axis,
width=12cm,
height=4cm,
% use a stacked bar char
ybar stacked,
% we add the ticklabels as part of the table, so no xticks needed
xtick=\empty,
% set distance between yticks
ytick distance=200,
% and add grid lines
grid=major,
% only need left y-axis line
axis y line=left,
x axis line style={draw=none},
% divide axis width by twice the number of rows, so that the whitespace between
% bars is the same as the bar width ...
bar width={\pgfkeysvalueof{/pgfplots/width}/(2*\Nrows+2)},
% 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={\pgfkeysvalueof{/pgfplots/width}/(2*\Nrows+2)}},
ymin=0,
ylabel={Number of interactions},
xlabel={$p$-value},
% 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}
\path (ax.north east);
\pgfgetlastxy{\MyAxisW}{\MyAxisH}
\tikzset{
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
}
}
% 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,draw=none},anchor=north east,row sep=0pt,outer sep=0pt,inner ysep=0pt] (m) at (c-1-1.north west)
{
\node {\ref{dataV}}; & \node{Non-validated}; \\
\node {\ref{dataNV}}; & \node{Validated}; \\
};
% draw center line of legend
\draw (m.west) -- (m.east);
\end{tikzpicture}
\end{document}
对于那些想知道这有什么不同的人来说:现在可以scale
通过一个tikzpicture
选项来编辑整个内容。图表宽度可以在其他地方设置。选择较小的字体和/或较宽的条形图,text width
就align
可以了不是设置图形宽度。
-我不喜欢这种呈现数据的方式 -但这是可能的