如何在Mathematica中真正实现BarSpacing选项?

时间:2011-09-03 13:14:32

标签: wolfram-mathematica plot bar-chart

我正在尝试实施DateListBarChart函数,该函数采用过时数据并输出带有与DateListPlot相同展示位置的条形图。如果给出相同的数据,它们必须在相同的水平位置绘制数据,因此可以使用Show组合它们。我发现很难将BarSpacing的设置设置为正确,以便绘图的水平范围不会改变,并且条形基本上保持在相同的位置。

我无法推断出正确的缩放比例,因此BarSpacing->{0.2,0.3}导致该组条的可用x轴长度的20%被占用该组中条形的间距,而30%为条形组之间的间距。出于技术原因,我通过将内容传递给RectangleChart来实现此目的。根据文档,BarSpacing被视为RectangleChart中的绝对单位。显然,如果有更多的系列,间隙的绝对尺寸需要更小,并且条形需要更窄。

一些例子:

arList = FoldList[0.9 #1 + #2 &, 0.01, RandomReal[NormalDistribution[0, 1], 24]]

{0.01, 0.334557, 2.02709, 1.1878, 1.9009, 3.08604, 2.36652, 3.04111, 
3.32364, 3.22662, 3.12626, 2.59118, 1.69334, 1.21069, 0.23171, 
0.689415, -0.852649, -0.124624, 0.58604, -0.481886, 0.221074, 
-0.300329, 2.36137, 0.427789, -1.47747}

dists = RandomChoice[{3, 4}, Length[arList]]
{4, 4, 4, 3, 4, 3, 4, 3, 4, 4, 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, 3, 3, 3, 3, 3}

结果:

RectangleChart[Transpose[{dists - 0 - 0/2, arList}], 
 PlotRange -> {{0, 100}, {-2, 4}}, ChartStyle -> EdgeForm[None], 
 Frame -> True, GridLines -> Automatic, BarSpacing -> {0, 0}]

enter image description here

RectangleChart[Transpose[{dists - 0.7 - 0.5/2, arList}], 
 PlotRange -> {{0, 100}, {-2, 4}}, ChartStyle -> EdgeForm[None], 
 Frame -> True, GridLines -> Automatic, BarSpacing -> {0.7, 0.5}]

enter image description here

注意数据如何沿x轴跨越与前一个示例相同的距离。

在尝试绘制多个系列时会更加混乱(在此示例中也是相同的,为了说明)。

RectangleChart[
 Transpose[{{dists - i/2 - j/2, arList}, {dists - i/2 - j/2, 
  arList}}, {2, 3, 1}], PlotRange -> {{0, 180}, {-2, 4}}, 
 ChartStyle -> EdgeForm[None], Frame -> True, Ticks -> None, 
  GridLines -> Automatic, BarSpacing -> {i, j}]

enter image description here

我一直在努力寻找合适的公式,以便自定义函数的BarSpacing设置(此处未见)会产生正确的间距和条宽,以便水平图范围不会改变正如BarSpacing所做的那样。

我错过了什么?

编辑:回应belisarius,这是我前进的一个例子。它的工作方式,(条形与线条不完全对齐,但这可能是我正在使用的日期)但是堆叠条形的情况无法用它们应该存在的条形图,就像任何一种条形图本身就有多个系列。 (我为日期标签放置算法感到自豪:工作中的权力不想放弃那种外观。)

enter image description here

这是一个不起作用的人。数据应填充水平范围。 (不同的宽度条是故意的 - 它是年度和季度数据的组合。)

enter image description here

编辑2

我记得为什么我没有在Filling中使用DateListPlot来绘制Mike Honeychurch的包装中的条形图 - 如果除了非常瘦的条纹之外还有其他任何东西,它们最终会有顶边在错误的地方。

DateListPlot[{dateARList}, 
 PlotStyle -> {AbsolutePointSize[6], Yellow}, Filling -> {1 -> 0}, 
 FillingStyle -> {1 -> {{AbsoluteThickness[12], Darker[Red, 0.25]}}}, 
 PlotRange -> All]

enter image description here

2 个答案:

答案 0 :(得分:9)

也许使用ChartElementFunction选项代替BarSpacing帮助。例如,代码中的barplot会绘制一个条形图,左边的每个条的边距为gapl,而gapr和{{1}的右侧为gapl }是条的总宽度的分数

gapr

用法:

绘制没有间隙的原始条形图

scale[{{xmin_, xmax_}, {ymin_, ymax_}}, {gapl_, gapr_}] :=
 {{xmin (1 - gapl) + xmax gapl, ymin}, {xmax (1 - gapr) + xmin gapr, ymax}}

barplot[dists_, arList_, {gapl_, gapr_}, opts___] := 
 RectangleChart[Transpose[{dists, arList }], opts, 
  Frame -> True, 
  GridLines -> Automatic, BarSpacing -> 0,
  ChartElementFunction -> (Rectangle @@ scale[#, {gapl, gapr}] &)]

rectangle chart with no gaps

这将绘制两侧边距为0.2的条形图,这会产生条形图,其间隙为条形总宽度的0.4倍。请注意,条形图的位置与第一个图形中的位置匹配。

barplot[dists, arList, {0, 0}]

barchart with gaps

您可以通过执行类似

的操作来绘制多个系列
barplot[dists, arList, {0.2, 0.2}]

two series in one plot

答案 1 :(得分:4)

您可以使用FillingStyle来缓解有关CapForm["Butt"]的投诉。

list = {0.01, -0.81, 0.12, 0.81, 1.79, 1.1, 0.41, 1., 1.33, 1.08, 
  2.16, 1.13, 1.92, 1.64, 1.31, 1.94, 1.71, 0.91, 2.32, 0.95, 1.29, 
  1.28, 2.97, 4.45, 5.11}

DateListPlot[list, {2000, 8}, 
 PlotStyle -> {AbsolutePointSize[6], Yellow}, Filling -> {1 -> 0}, 
 FillingStyle -> {1 -> {{CapForm["Butt"], AbsoluteThickness[14], 
      Darker[Red, 0.25]}}}, PlotRange -> {0, 6}, ImageSize -> 400]

enter image description here