使用 pgfplots 绘制特定条形图:条形颜色 = 类别

使用 pgfplots 绘制特定条形图:条形颜色 = 类别

我想使用创建一个条形图pgfplots。在这个图中,条形应该代表类别。因此,一种颜色代表一个类别。

类别如下:

  • 0-8 无
  • 9-13 最低限度
  • 14-19 略有
  • 20-28 中重
  • 29-63 重型

后面还有一个例子,但是所有的条都是同一种颜色:

\documentclass[11pt]{standalone}
\usepackage[T1]{fontenc}
\usepackage{fixltx2e}
\usepackage{pgfplots}

\pgfplotsset{compat=1.8}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    xbar,
    width=12cm,
    height=8cm,
    xmajorgrids=true,
    yticklabel={\#\ifnum\ticknum<9 0\fi\pgfmathprintnumber\tick},
    ytick={1,2,...,10},
    xmin=0,
    xmax=36,
    xtick={5,10,...,30},
    xlabel={Sum},
    ylabel={Participants},
    %nodes near coords,
    ymin=0.25,
    ymax=10.75,
  ]
    \addplot coordinates
      {(4,1) (16,2) (16,3) (33,4) (5,5) (10,6) (20,7) (8,8) (15,9) (5,10)};
  \end{axis}
\end{tikzpicture}
\end{document}

之后它应该看起来像附图。我不确定这是否可行。参与者的顺序(#01 - #10)应该保持连续。 在此处输入图片描述

答案1

以下是两种不同的方法(代码在底部):

  1. 使用带有急剧过渡的彩色图的“假”条形图(实际上是散点图)。

  2. 对每个类别使用不同的\addplot命令,过滤掉所有不属于当前类别的值。

配色方案取自Colorbrewer 网站


单人\addplot带彩图:

\documentclass[11pt, border=5mm]{standalone}
\usepackage{pgfplots}


\definecolor{ylgnbu1}{RGB}{255, 255, 204}
\definecolor{ylgnbu2}{RGB}{161, 218, 180}
\definecolor{ylgnbu3}{RGB}{65, 182, 196}
\definecolor{ylgnbu4}{RGB}{44, 127, 184}
\definecolor{ylgnbu5}{RGB}{37, 52, 148}

\pgfplotsset{
    colormap={colorbrewer-ylgnbu}{[1pt]
        color(0pt)=(ylgnbu1);
        color(85pt)=(ylgnbu1);
        color(85pt)=(ylgnbu2);
        color(135pt)=(ylgnbu2);
        color(135pt)=(ylgnbu3);
        color(195pt)=(ylgnbu3);
        color(195pt)=(ylgnbu4);
        color(285pt)=(ylgnbu4);
        color(285pt)=(ylgnbu5);
        color(630pt)=(ylgnbu5);
    },
}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    colorbar,
    colorbar style={
        major tick length=0pt,
        ytick={4,11,16.5,24,46},
        yticklabels={None,Minimal,Slightly,Medium heavy,Heavy}
    },
    point meta min=0, point meta max=63,
    scatter,
    scatter src=x,
    only marks,
    clip mode=individual,
    scatter/@pre marker code/.append code={
            \pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
            \pgfmathsetmacro\negheight{-\pgfplotspointmeta}         
            \fill [draw=black] (axis direction cs:0,0.3) rectangle (axis direction cs:\negheight,-0.3);
            \pgfplotsset{mark=none}
        },
    xmin=0,
    width=12cm,
    height=8cm,
    xmajorgrids=true,
    yticklabel={\#\ifnum\ticknum<9 0\fi\pgfmathprintnumber\tick},
    ytick={1,2,...,10},
    xmin=0,
    xmax=36,
    xtick={5,10,...,30},
    xlabel={Sum},
    ylabel={Participants},
    %nodes near coords,
    ymin=0.25,
    ymax=10.75,
  ]![enter image description here][3]
    \addplot coordinates
      {(4,1) (16,2) (16,3) (33,4) (5,5) (10,6) (20,7) (8,8) (15,9) (5,10)};
  \end{axis}
\end{tikzpicture}
\end{document}

使用单独的\addplot命令。

\documentclass[11pt, border=5mm]{standalone}
\usepackage{pgfplots, pgfplotstable}

\definecolor{ylgnbu1}{RGB}{255, 255, 204}
\definecolor{ylgnbu2}{RGB}{161, 218, 180}
\definecolor{ylgnbu3}{RGB}{65, 182, 196}
\definecolor{ylgnbu4}{RGB}{44, 127, 184}
\definecolor{ylgnbu5}{RGB}{37, 52, 148}

\pgfplotscreateplotcyclelist{colorbrewer-ylgnbu}{
{fill=ylgnbu1, draw=black},
{fill=ylgnbu2, draw=black},
{fill=ylgnbu3, draw=black},
{fill=ylgnbu4, draw=black},
{fill=ylgnbu5, draw=black},
}


\pgfplotstableread{
Sum Participants
4 1
16 2
16 3
33 4
5 5
8 6
20 7
8 8
15 9
5 10
}\datatable
\newcounter{plotindex}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    xbar=0pt, bar shift=0pt,
    cycle list name=colorbrewer-ylgnbu,
    xmin=0,
    width=12cm,
    height=8cm,
    xmajorgrids=true,
    yticklabel={\#\ifnum\ticknum<9 0\fi\pgfmathprintnumber\tick},
    ytick={1,2,...,10},
    xmin=0,
    xmax=36,
    xtick={5,10,...,30},
    xlabel={Sum},
    ylabel={Participants},
    ymin=0.25,
    ymax=10.75,
    legend entries={None,Minimal,Slightly, Medium heavy,Heavy},
    legend cell align=left
  ]
  \pgfplotsinvokeforeach{1,...,5}{
    \addlegendimage{fill=ylgnbu#1,draw=black,area legend}
  }
  \pgfplotsinvokeforeach{0:8,9:13,14:19,20:28,29:63}{
    \addplot +[restrict x to domain=#1] table {\datatable};
    }
  \end{axis}
\end{tikzpicture}
\end{document}

答案2

在此处输入图片描述 在此处输入图片描述

这是一个Asymptote解决方案,包括一个rangebargraph.asy模块(需要做更多工作来处理可能的情况变化)。级别opacity用于从基本颜色中获取颜色变化catPen,可以为图表设置。

crbg.tex

\begin{filecontents*}{rangebargraph.asy}
import graph;
import palette;

struct coloredRangeBarGraph{  
  string[] catName;

  real[] catRange;

  pen catPen=darkgreen;
  pen[] catOpacity;

  int[] data;

  int getCat(real dataPoint,real[] catRange){
    for(int i=0;i<catRange.length;++i){
      if(dataPoint<catRange[i]) return i;
    }
    return catRange.length;
  }

  real boxwidth;;

  pen axisPen=darkblue;

  real xmin;
  real xmax;

  real ymin;
  real ymax;

  void drawBars(){
    for(int i=0;i<data.length;++i){
      filldraw(box((0,i+1-boxwidth),(data[i],i+1+boxwidth))
      ,catOpacity[getCat(data[i],catRange)]
      );
    }
  }

  void drawLegend(real w=1, real h=1){
    for(int i=0;i<catName.length;++i){
      filldraw(box( (xmax+1,ymax-0.5-i-h/2),(xmax+1+w,ymax-0.5-i+h/2) ),catOpacity[i]);
      label(Label(catName[i]),(xmax+1+w,ymax-0.5-i),E);
    }
  }

  void drawAxes(){
    ylimits(ymin,ymax);
    xaxis("Sum"
    ,BottomTop(extend=true)
    ,p=axisPen
    ,xmin,xmax,Ticks(extend=true,Step=5,pTick=lightblue,begin=false));

    yaxis("Participants"
      ,ymin,ymax
      ,p=axisPen
      ,LeftTicks(ticklabel=new string(real x){return format("\#%#.2d",(int)x);} 
        ,Step=1
        ,beginlabel=false
        ,pTick=darkblue
      )
    );
  };  

  void operator init(int[] data
    ,string[] catName=new string[]{"None","Minimal","Slightly","Medium heavy","Heavy"}
    ,int[] catRange=new int[]{9,14,20,29}
    ,pen catPen=darkgreen
    ,pen[] catOpacity=new pen[]{
        catPen+opacity(0.05),
        catPen+opacity(0.2),
        catPen+opacity(0.4),
        catPen+opacity(0.8),
        catPen+opacity(1)}
    ,real boxwidth=0.5
    ,pen axisPen=darkblue
    ,real xmin=0
    ,real xmax=max(data)+1
    ,real ymin=0
    ,real ymax=data.length+0.5
    ){
    this.data=copy(data);
    this.catName   =catName   ; 
    this.catRange  =catRange  ;
    this.catPen    =catPen    ;
    this.catOpacity=catOpacity;
    this.boxwidth  =boxwidth  ;
    this.axisPen   =axisPen   ;
    this.xmin      =xmin      ;
    this.xmax      =xmax      ;
    this.ymin      =ymin      ;
    this.ymax      =ymax      ;
  }
};
\end{filecontents*}
\documentclass[10pt,a4paper]{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}
\begin{document}

\begin{figure}
\begin{asy}
import rangebargraph;
size(300,200,IgnoreAspect);
int[] data={4, 16, 16, 33, 5, 10, 20, 8, 15, 5,};
coloredRangeBarGraph g=coloredRangeBarGraph(data);
g.drawBars();
g.drawAxes();
g.drawLegend();
\end{asy}
\caption{Default}
\end{figure}

\begin{figure}
\begin{asy}
import rangebargraph;
size(400,300,IgnoreAspect);
int[] data={29,38,27,8,57,9,49,23,18,48,4,42,25,5,30,37};
coloredRangeBarGraph g=
   coloredRangeBarGraph(data,boxwidth=0.309
     ,catPen=darkblue
     ,axisPen=olive     
     , xmax=62     
     );
g.drawBars();
g.drawAxes();
g.drawLegend();
\end{asy}
\caption{Customized}
\end{figure}

\end{document}

为了处理它latexmk,请创建文件latexmkrc

sub asy {return system("asy '$_[0]'");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");

然后运行latexmk -pdf crbg.tex

相关内容