带有带框字符串的条形图

带有带框字符串的条形图

我有一张.csv包含分类数据和数字数据的表。

  • 第一列包含类别,以字符串表示。
  • 第二列包含属于每个类别的观测值数量。这是表中唯一的数字数据。
  • 其余列包含每个观察的各种出现情况,这些出现情况是字符串。

直观地了解文件的结构:

CATEGORIES  NOBS    OCCURRENCE1     OCCURRENCE2     OCCURRENCE3
Street      3       Street A        Street XXXXX    Street YY 
Square      2       Square ZZZZ     Square B        ''
Lane        1       Lane XXXXX      ''              ''
Park        1       Park A          ''              ''

注意,有些字符串可能为空。此外,字符串的长度是可变的。

从这些数据开始,我希望获得如下所示的数字。

我在标题中称之为“包含方框字符串的条形图”

理想情况下,我有兴趣总体长度每行一致NOBS。这可能需要减小某些行的字体大小,如果需要,我准备手动执行此操作。但是,必须确定各个框的宽度,以便生成与 NOBS 一致的条形图的整体大小。另一种方法是使用宽度等于最长字符串的固定文本框大小:这样,每个条形图的整体长度在构造上将与 NOBS 一致。

我曾尝试研究如何实现这种类型的图形,但迄今为止失败了。我是否完全错过了一些软件包或其他有用的解决方案?任何帮助都将不胜感激。

答案1

这是朝着正确的方向发展的吗?

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{datatable.csv}
CATEGORIES;NOBS;OCCURRENCE1;OCCURRENCE2;OCCURRENCE3
Street;3;Street A;Street XXXXX;Street YY 
Square;2;Square ZZZZ;Square B;''
Lane;1;Lane XXXXX;'';''
Park;1;Park A;'';''
\end{filecontents*}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.16}
\newcounter{realitems}
\begin{document}
\begin{tikzpicture}[font=\sffamily,header/.style={text
    width=2.4cm,align=left,fill=gray!20,minimum height=8mm,draw,inner xsep=1ex},
    funky bar/.cd,inner sep/.initial=1ex,width/.initial=2.1cm]
 % your empty cell indicator
 \edef\none{''}
 % load table and figure out how many rows and columns it has
 \pgfplotstableread[col sep=semicolon]{datatable.csv}\loadedtable
 \pgfplotstablegetrowsof{\loadedtable} 
 \pgfmathtruncatemacro{\NumRows}{\pgfplotsretval-1} 
 \pgfplotstablegetcolsof{\loadedtable} 
 \pgfmathtruncatemacro{\NumCols}{\pgfplotsretval-1}
 % loop 
  \foreach \Row in {0,...,\NumRows}
  {\setcounter{realitems}{0} %measure the items
   \foreach \Col in {2,...,\NumCols}
    {\pgfplotstablegetelem{\Row}{[index]\Col}\of{\loadedtable}
      \ifx\pgfplotsretval\none
      \else
       \stepcounter{realitems}
       \ifnum\number\value{realitems}=1
        \xdef\CurLst{"\pgfplotsretval"}
        \pgfmathsetmacro{\tmpwd}{width("\pgfplotsretval")}
        \xdef\tmpwd{\tmpwd}
       \else
        \xdef\CurLst{\CurLst,"\pgfplotsretval"}
        \pgfmathsetmacro{\tmpwd}{\tmpwd+width("\pgfplotsretval")}
        \xdef\tmpwd{\tmpwd}
       \fi
      \fi
    }
   \typeout{\Row,\CurLst}   
   \pgfmathsetmacro{\ratio}{\number\value{realitems}*
    (\pgfkeysvalueof{/tikz/funky bar/width}-2*\pgfkeysvalueof{/tikz/funky bar/inner sep})/\tmpwd}   
   \pgfplotstablegetelem{\Row}{[index]0}\of{\loadedtable}
   \ifnum\Row=0 
    \node[header,alias=n-\Row-0] (H\Row) {\pgfplotsretval};
   \else
    \node[header,alias=n-\Row-0,below=-\pgflinewidth\space of H\the\numexpr\Row-1] (H\Row) {\pgfplotsretval};
   \fi
   \foreach \X [evaluate=\X as \PrevX using {int(\X-1)}] in {1,...,\number\value{realitems}}
   {\ifnum\number\value{realitems}=1
    \pgfmathsetmacro{\myitem}{\CurLst}
    \typeout{\myitem}
    \pgfmathsetmacro{\mywidth}{\pgfkeysvalueof{/tikz/funky bar/width}}
    \node[anchor=center,inner sep=0pt,scale=\ratio] (n-\Row-\X)
    at ([xshift=\mywidth/2]n-\Row-\PrevX.east)  {\myitem};
    \draw ([yshift=-\pgflinewidth/2]n-\Row-0.north -| n-\Row-\PrevX.east)
    -- ++ (\mywidth pt,0) |- ([yshift=\pgflinewidth/2]n-\Row-0.south -| n-\Row-\PrevX.east);;
   \else
    \pgfmathsetmacro{\myitem}{{\CurLst}[\X-1]}
    \pgfmathsetmacro{\mywidth}{2*\pgfkeysvalueof{/tikz/funky bar/inner sep}+\ratio*width("\myitem")}
    \node[anchor=center,inner sep=0pt,scale=\ratio,
    right={ifthenelse(\X==1,1,2)*\pgfkeysvalueof{/tikz/funky bar/inner sep}}
    of n-\Row-\PrevX] (n-\Row-\X) {\myitem};
    \draw ([yshift=-\pgflinewidth/2]n-\Row-0.north -| n-\Row-\PrevX.east)
    -- ++ (\mywidth pt,0) |- ([yshift=\pgflinewidth/2]n-\Row-0.south -| n-\Row-\PrevX.east);;
    \fi
   }
   }
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容