直方图条形具有不同的条形颜色

时间:2019-09-24 14:21:16

标签: colors histogram stata

我想根据十分位数断点,获得具有给定颜色的交替渐变的直方图,如下图所示:

enter image description here

示例数据:

clear
input float dn3001 double hw0010
  1219000 2823.89408574376
   -16390 520.112200750285
   121010 238.732322261911
   953839 221.316063150235
   465000 247.280750487467
     -870 280.305382323347
    96000 2946.16661611018
    69500  355.33497718705
   113000 1421.43087298696
    30500 616.914514202173
    20000 3389.34765405599
   154000 305.674687642557
   440500 525.694777777734
    56870 1823.24691219821
   330500 376.651172915574
   101000 465.098273950744
 401046.5 660.816203440777
    31872 1693.02190101773
   220345 603.326244510505
   193360 677.527413164373
   196300 568.436679602066
   222640 427.051692314575
   510500 318.557431587468
   131450 1388.72862441839
   122300 532.996690473983
      305 2441.72289873923
   313500 292.610321722557
   184500 2699.67735757755
1615564.6 386.944439319246
   126528 3018.77523617479
   711110 511.604491869939
   127440 256.968118266053
   424900   1620.366555701
    95491 3097.46262561529
   287500 413.119620218929
    70050 2119.47171174278
    75460 299.232446656805
   210500 290.391474820414
   135800 292.141670444933
   119924 303.953183619671
    81075 1568.41438245214
      152 289.175871985445
    73000 2551.12752046544
   246500 327.474430367518
   159960 2350.26463245568
    14522  456.56909870547
   139000 319.451311193507
    68661 2771.34087931684
 214089.7 388.589383036063
   927800 849.088069585408
     7840 1512.71702946577
   140140 852.940547469624
21646.566 2405.47949923772
end

下面的代码会产生一个条形不均匀的图形:

xtile aux = dn3001 [aw=hw0010], nq(10)
_pctile dn3001[aw=hw0010], nq(10)
sort dn3001 
list dn3001 aux
return list
scalar p10=r(r1)
scalar p20=r(r2)
scalar p30=r(r3)
scalar p40=r(r4)
scalar p50=r(r5)
scalar p60=r(r6)
scalar p70=r(r7)
scalar p80=r(r8)
scalar p90=r(r9)
drop aux
sum dn3001 [aw=hw0010], d
scalar p1=r(p1)
scalar p95=r(p95)
twoway histogram dn3001 if dn3001>=scalar(p1) & dn3001<scalar(p10),  bcolor(green%20) freq legend(off) ///
    || histogram dn3001 if dn3001>=scalar(p10) & dn3001<scalar(p20),  bcolor(green) freq legend(off) ///
    || histogram dn3001 if dn3001>=scalar(p20) & dn3001<scalar(p30),  bcolor(green%20) freq legend(off) /// 
    || histogram dn3001 if dn3001>=scalar(p30) & dn3001<scalar(p40),  bcolor(green) freq legend(off) ///
    || histogram dn3001 if dn3001>=scalar(p40) & dn3001<scalar(p50),  bcolor(green%20) freq legend(off) /// 
    || histogram dn3001 if dn3001>=scalar(p50) & dn3001<scalar(p60),  bcolor(green) freq legend(off) ///
    || histogram dn3001 if dn3001>=scalar(p60) & dn3001<scalar(p70),  bcolor(green%20) freq legend(off) ///
    || histogram dn3001 if dn3001>=scalar(p70) & dn3001<scalar(p80),  bcolor(green) freq legend(off) ///
    || histogram dn3001 if dn3001>=scalar(p80) & dn3001<scalar(p90),  bcolor(green%20) freq legend(off) ///
    || histogram dn3001 if dn3001>=scalar(p90) & dn3001<scalar(p95),  bcolor(green) freq legend(off)

Output

如何获得相同的条形宽度?

2 个答案:

答案 0 :(得分:2)

评论(而不是一系列评论)比您寻求的答案要多,但该图不适合评论。

您的方法似乎注定要失败-如果不失败,那就极端困难。

  1. 我们无法保证任何分位数仓位限制都会与任何直方图仓位限制匹配。

  2. 同样,不能保证相邻分位数之间的差异是您可能选择的任何直方图bin宽度的简单倍数。您可能会尝试根据更频繁的分位数仓来给条形上色,以此来弄虚作假,但这会忽略细节。因此,假设您的直方图条针对[100,200),但是该间隔中的某些值属于一个分位数仓,而某些值属于另一个分位数仓:您会怎么做?如果3个或更多分位箱落在直方图中,您会怎么做?

  3. 通过指定多个直方图而不指定起点或区间宽度,可以释放无政府状态。 Stata将部分基于样本量为每个直方图做出单独的决策。那就是您的代码要执行的操作,而不是您想要的。

  4. 您的直方图对您使用的分析权重一无所知。

除此之外,您的问题还引发了各种不必要的难题。

  • 为什么产生aux却什么也不做? SO的标准技巧是显示解释问题所需的最少代码。

  • 您说您对十分位数感兴趣,但不一致地还使用1%和95%的百分位数。

为什么您拥有如此权重非常不同的不规则值,目前尚不清楚,但对于您的紧迫问题而言并不重要。但是,所有这些使我觉得无法从数据中轻松或有效地获得像示例图那样的直方图。您只有53个数据点,因此权重与无法拥有53个以上的非空箱无关紧要。

不使用直方图就可以直接显示bin限制相对于数据的下降方式。

使用您的示例数据(谢谢!),我这样做

xtile aux = dn3001 [aw=hw0010], nq(10)

quantile dn3001, ms(none) mla(aux) mlabpos(0) scheme(s1color) rlopts(lc(none))

enter image description here

我通常会使用对数刻度,但使用负值可以排除这种情况。

在这里,我不仅仅讨论严格的编程问题,但这个问题不可避免地引发了我要解决的问题。

答案 1 :(得分:2)

这是一种可能的方法:

twoway__histogram_gen dn3001, freq bin(50) generate(b a, replace)

_pctile dn3001 [aw=hw0010], nq(10)

return list

scalars:
                 r(r1) =  20000
                 r(r2) =  30500
                 r(r3) =  68661
                 r(r4) =  75460
                 r(r5) =  96000
                 r(r6) =  126528
                 r(r7) =  159960
                 r(r8) =  196300
                 r(r9) =  440500

generate group = .

forvalues i = 9(-1)1 {
    replace group = `i' if a <= `r(r`i')'
}

replace group = 10 if a > `r(r9)' & _n <= 20
list a b group in 1 / 20, sepby(group)

     +-----------------------+
     |         a   b   group |
     |-----------------------|
  1. | -70.45375   6       1 |
     |-----------------------|
  2. |  32568.64   4       3 |
  3. |  65207.73   7       3 |
     |-----------------------|
  4. |  97846.82   4       6 |
     |-----------------------|
  5. |  130485.9   9       7 |
     |-----------------------|
  6. |    163125   2       8 |
  7. |  195764.1   4       8 |
     |-----------------------|
  8. |  228403.2   3       9 |
  9. |  261042.3   1       9 |
 10. |  293681.4   1       9 |
 11. |  326320.5   2       9 |
 12. |  391598.7   1       9 |
 13. |  424237.8   2       9 |
     |-----------------------|
 14. |  456876.8   1      10 |
 15. |    522155   1      10 |
 16. |  717989.6   1      10 |
 17. |  913824.1   1      10 |
 18. |  946463.3   1      10 |
 19. |   1207576   1      10 |
 20. |   1599245   1      10 |
     +-----------------------+

结果:

twoway (bar b a, barwidth(25000) legend(off)) ///
       (bar b a if group == 3, barwidth(25000) color(green)) ///
       (bar b a if group == 9, barwidth(25000) color(red))

enter image description here