我正在尝试绘制调查结果。但是,我想根据结果打开或关闭一个栏(无答案)。也就是说,如果没有空答案,则无需显示它。
但是,我如何才能隐藏图中的其中一个条形图(给定条件)。此外,我正在使用该statistics
库自动计算直方图。有没有办法动态更改箱体?或者使用后端更容易pgfplots
?
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{data.csv}
a;b;c
4;3;3
1;3;1
1;4;4
1;3;4
2;4;4
2;4;4
4;3;-1
4;4;4
3;3;3
2;4;3
3;3;3
3;2;2
4;4;3
\end{filecontents}
\usepackage{pgfplots, pgfplotstable}
\usepgfplotslibrary{statistics}
\pgfplotstableread[col sep = semicolon]{data.csv}\mydata
\makeatletter
\newcommand*\NNC{\pgfmathprintnumber{\pgfkeysvalueof{/data point/y}}}
\newcommand*\enlargexlimits{.1} % default value for enlarge x limits
\pgfplotsset{
width=\linewidth,
height=0.5\linewidth,
grid style={dashed}, % make the grid dashe
% Bottom nodes
calculate full offset/.code={
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
\pgfmathsetmacro\testmacro{((\pgfplotspointmeta-\pgfkeysvalueof{/pgfplots/ymin})*10^\pgfplots@data@scale@trafo@EXPONENT@y)*\pgfplots@y@veclength}
\pgfkeys{/pgf/fpu=false}
},%
nodes near coords bottom/.style={
every node near coord/.append style={
white,
/pgfplots/calculate full offset,
yshift=-\testmacro,
xshift={
(\pgfkeysvalueof{/pgfplots/width}-45pt) % every plot is 45pt smaller then the width
/(1+2*\enlargexlimits) % correction for enlarge x limits
/\pgfkeysvalueof{/pgfplots/hist/bins} % number of bins
/2% shift only half of bin width
}
},
nodes near coords={%
\pgfmathparse{
\pgfkeysvalueof{/data point/x}<0.9*\pgfkeysvalueof{/pgfplots/hist/data max}?%
"\noexpand\NNC"% if true print nodes near coords
:% if false suppress the additional node near coords
}\pgfmathresult%
},
},%
% Minimal bar grid, sets the grid on top and white
minimal bar grid/.style={
axis on top,
ymajorgrids, tick align=inside,
major grid style={draw=white},
tickwidth=0pt,
grid style={solid},
axis x line*=bottom,
y axis line style={opacity=0},
legend style={
font=\footnotesize,
draw=none %eliminate the border
},
},
minimal ybar interval/.style={
ybar interval,
bar interval width=.8pt,
minimal bar grid,
nodes near coords={\pgfmathprintnumber[fixed zerofill,precision=0]{\pgfplotspointmeta}},
nodes near coords bottom,
},
bar color/.style={
gray,
fill=gray,
}
}
\makeatother
\newcommand{\myplot}[1]{%
\begin{tikzpicture}
\begin{axis}[
minimal ybar interval,
ymin=0,
enlarge x limits=0,
xticklabels={No Ans.,A,B,C,D},
x tick label style={font=\footnotesize}
]
\addplot +[
bar color,
hist={bins=5,data min=0,data max=5}
] table [y=#1] {\mydata};
\end{axis}
\end{tikzpicture}
}
\pagestyle{empty}
\begin{document}
\myplot{a}
\myplot{b}
\myplot{c}
\end{document}
例如,对于前两个图,我希望只显示从 A 到 D 的条形图,但在最后一个图中(其中有一些未回答的问题),我希望显示无答案的数量。
答案1
继续@percuesse 的评论:
在之后添加以下几行\makeatletter
:
\makeatletter
\def\pgfplotsplothandlerhistadvancebin#1{
\pgfplotsarrayselect{#1}\of{pgfp@hist}\to\pgfplots@loc@TMPa%
\pgfplotsutil@advancestringcounter\pgfplots@loc@TMPa
\pgfplotsarrayletentry{#1}\of{pgfp@hist}=\pgfplots@loc@TMPa
% ↑↑↑↑↑↑↑ old definition ↑↑↑↑↑↑↑
% ↓↓↓↓↓↓↓ I added this line ↓↓↓↓↓↓↓
\message{pglplots express: bin number #1 is now counting to \pgfplots@loc@TMPa.^^J}
}
现在您可以看到 pgfplots 如何计算您的数据。(参见附录 A)应该相对容易一些
\pgfplotsplothandlerhistadvancebin
例如添加 更多 的 东西\expandafter\gdef\csname pgfplotstellmeifbin#1isnonempty\endcsname{YES}
.- 传递你的数据
\addplot
。 - 放弃该情节。(但
\gdef
保留定义的宏。) - 开始一个新的情节,这一次你知道哪个条是非空的。
进而?
让我们从新文档开始。请注意,我修复了hist/symbolic coords/.style
from的定义pgfplotsplothandlers.code.tex
。
\documentclass[border=9,tikz]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{statistics}
\makeatletter
\def\pgfplotsplothandlerhistadvancebin#1{
\pgfplotsarrayselect{#1}\of{pgfp@hist}\to\pgfplots@loc@TMPa
\pgfplotsutil@advancestringcounter\pgfplots@loc@TMPa
\pgfplotsarrayletentry{#1}\of{pgfp@hist}=\pgfplots@loc@TMPa
% ↑↑↑↑↑↑↑ old definition ↑↑↑↑↑↑↑
% ↓↓↓↓↓↓↓ I added this line ↓↓↓↓↓↓↓
\expandafter\gdef\csname bin#1isnonempty\endcsname{YES}
}
\pgfplotsset{
hist/symbolic coords/.style={
/pgfplots/symbolic coords={hist/data}{#1},
/pgfplots/symbolic coords={x}{#1},
}
}
\pgfplotstableread[row sep=\\]{
datb\\
A\\A\\A\\A\\
B\\B\\
C\\C\\C\\C\\C\\
D\\D\\D\\
}\mydatb
\pgfplotstableread[row sep=\\]{
datb\\
C\\C\\C\\C\\C\\
D\\D\\D\\
}\mydatc
\pgfplotstableread[row sep=\\]{
datc\\
A\\A\\A\\A\\
B\\B\\
D\\D\\D\\
}\mydatd
\pgfplotstableread[row sep=\\]{
datb\\
A\\A\\A\\A\\
B\\B\\
C\\C\\C\\C\\C\\
}\mydate
\begin{document}
因此我们有四个图:
\def\myplot#1{
\begin{tikzpicture}
\begin{axis}[ybar interval,ymin=0,xmin=A,xmax=PhantomMax,
hist={bins=4,symbolic coords={A,B,C,D,PhantomMax}}]
\addplot table[y index=0]{#1};
\end{axis}
\end{tikzpicture}
}
\myplot\mydatb
\myplot\mydatc
\myplot\mydatd
\myplot\mydate
然后我们可以报告结果:
\def\YES{YES}
\newcount\countofnonzero
\def\myplot#1{
\countofnonzero=0
\foreach\i in{0,...,3}{\expandafter\gdef\csname bin\i isnonempty\endcsname{NO}}
\begin{tikzpicture}
\begin{axis}[ybar interval,ymin=0,xmin=A,xmax=PhantomMax,
hist={bins=4,symbolic coords={A,B,C,D,PhantomMax}}]
\addplot table[y index=0]{#1};
\end{axis}
\node at(current bounding box.south)[yshift=-10]{
\foreach\i in{0,...,3}{
\expandafter\let\expandafter\YESorNO\csname bin\i isnonempty\endcsname
\YESorNO
\ifx\YESorNO
\YES\global\advance\countofnonzero1
\fi
}
total=\the\countofnonzero
};
\end{tikzpicture}
}
\myplot\mydatb
\myplot\mydatc
\myplot\mydatd
\myplot\mydate
最后我们可以正确地绘制它们:
\def\myplot#1{
\countofnonzero=0
\gdef\listognonzero{}
\foreach\i in{0,...,3}{
\expandafter\gdef\csname bin\i isnonempty\endcsname{NO}}
\begin{tikzpicture}
\begin{axis}[ybar interval,ymin=0,xmin=A,xmax=PhantomMax,
hist={bins=4,symbolic coords={A,B,C,D,PhantomMax}}]
\addplot table[y index=0]{#1};
\end{axis}
\end{tikzpicture}
\foreach\i/\a in{0/A,1/B,2/C,3/D}{
\expandafter\let\expandafter\YESorNO\csname bin\i isnonempty\endcsname
\ifx\YESorNO\YES
\global\advance\countofnonzero1
\xdef\listognonzero{\listognonzero\a,}
\fi
}
\xdef\listognonzero{\listognonzero PhantomMax}
\edef\numberofnonzero{\the\countofnonzero}
\begin{tikzpicture}
\begin{axis}[ybar interval,ymin=0,xmax=PhantomMax,
hist={bins=\numberofnonzero,symbolic coords/.expanded=\listognonzero}]
\addplot[fill=red]table[y index=0]{#1};
\end{axis}
\end{tikzpicture}
}
\myplot\mydatb
\myplot\mydatc
\myplot\mydatd
\myplot\mydate
附录 A
pglplots express: bin number 4 is now counting to 1.
pglplots express: bin number 1 is now counting to 1.
pglplots express: bin number 1 is now counting to 2.
pglplots express: bin number 1 is now counting to 3.
pglplots express: bin number 2 is now counting to 1.
pglplots express: bin number 2 is now counting to 2.
pglplots express: bin number 4 is now counting to 2.
pglplots express: bin number 4 is now counting to 3.
pglplots express: bin number 3 is now counting to 1.
pglplots express: bin number 2 is now counting to 3.
pglplots express: bin number 3 is now counting to 2.
pglplots express: bin number 3 is now counting to 3.
pglplots express: bin number 4 is now counting to 4.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <7> on input line 117.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <5> on input line 117.
Overfull \hbox (10.19409pt too wide) in paragraph at lines 117--118
[][]
[]
Underfull \hbox (badness 10000) in paragraph at lines 117--118
[]
pglplots express: bin number 3 is now counting to 1.
pglplots express: bin number 3 is now counting to 2.
pglplots express: bin number 4 is now counting to 1.
pglplots express: bin number 3 is now counting to 3.
pglplots express: bin number 4 is now counting to 2.
pglplots express: bin number 4 is now counting to 3.
pglplots express: bin number 3 is now counting to 4.
pglplots express: bin number 4 is now counting to 4.
pglplots express: bin number 3 is now counting to 5.
pglplots express: bin number 4 is now counting to 5.
pglplots express: bin number 3 is now counting to 6.
pglplots express: bin number 2 is now counting to 1.
pglplots express: bin number 4 is now counting to 6.
Overfull \hbox (10.19409pt too wide) in paragraph at lines 119--120
[][]
[]
Underfull \hbox (badness 10000) in paragraph at lines 119--120
[]
pglplots express: bin number 3 is now counting to 1.
pglplots express: bin number 1 is now counting to 1.
pglplots express: bin number 4 is now counting to 1.
pglplots express: bin number 4 is now counting to 2.
pglplots express: bin number 4 is now counting to 3.
pglplots express: bin number 4 is now counting to 4.
pglplots express: bin number 0 is now counting to 1.
pglplots express: bin number 4 is now counting to 5.
pglplots express: bin number 3 is now counting to 2.
pglplots express: bin number 3 is now counting to 3.
pglplots express: bin number 3 is now counting to 4.
pglplots express: bin number 2 is now counting to 1.
pglplots express: bin number 3 is now counting to 5.
Overfull \hbox (10.19409pt too wide) in paragraph at lines 121--122
[][]
[]
Underfull \hbox (badness 10000) in paragraph at lines 121--122
[]
答案2
您可以根据要显示的列对表格进行排序。然后,您可以计算唯一项目并将索引与相应的标签进行匹配。这当然是一种相当复杂的做事方式,我认为可以作为功能请求向 Christian Feuersänger 提出。但是,我注意到无论如何,bin 计算都存在一些敏感性。只需编写bins=3
您自己的代码,第二个代码就会报告0,7,6
元素计数可能是相对幅度和舍入问题。这也可以是一个错误报告。
我已删除大多数轴选项以减少混乱。
\documentclass{article}
\usepackage{pgfplotstable,xstring}
\pgfplotsset{compat=1.12}
\usepgfplotslibrary{statistics}
\newcount\mybincount
\pgfplotstableread[col sep = semicolon]{
a;b;c
4;3;3
1;3;1
1;4;4
1;3;4
2;4;4
2;4;4
4;3;-1
4;4;4
3;3;3
2;4;3
3;3;3
3;2;2
4;4;3
}\mydata
\newcommand{\myplot}[1]{%
\mybincount=0\def\myuniqueindex{}
\pgfplotstablesort[sort key=#1]\mysorteddata\mydata
\pgfplotstableforeachcolumnelement{#1}\of\mysorteddata\as\cell{%
\ifx\cell\prevvalue%IF they are the same ignore
\else% Otherwise
\xdef\prevvalue{\cell}% Make this the new previous value
\global\advance\mybincount by1% add to the unique items count and index
\expandafter\xdef\expandafter\myuniqueindex{\myuniqueindex,\cell}%
\fi%
\foreach\x/\y in{-1/{No Ans.},1/A,2/B,3/C,4/D}{% Replace strings with indices
\IfSubStr{\myuniqueindex}{\x}{%
\StrSubstitute{\myuniqueindex}{\x}{\y}[\myuniqueindex]%Then remove the preceeding comma
\IfBeginWith{\myuniqueindex}{,}{\StrGobbleLeft\myuniqueindex{1}[\myuniqueindex]}{}%
\global\let\myuniqueindex\myuniqueindex%
}{}}%
}\show\myuniqueindex\showthe\mybincount%
\begin{tikzpicture}
\begin{axis}[width=.4\textwidth,
ybar interval,
bar interval width=.8pt,
ymin=0,ytick={1,...,6},
enlarge x limits=0,
xticklabels/.expand once=\myuniqueindex,
x tick label style={scale=0.5}
]
\addplot +[fill=gray,hist={bins=\the\mybincount,data min=0,data max=5}] table [y=#1] {\mydata};
\end{axis}
\end{tikzpicture}}
\begin{document}
\myplot{a}\myplot{b}\myplot{c}
\end{document}