Re: DateListBarChart / Ticks in BarChart
- To: mathgroup at smc.vnet.net
- Subject: [mg104566] Re: DateListBarChart / Ticks in BarChart
- From: Luci Ellis <luci at verbeia.com>
- Date: Wed, 4 Nov 2009 01:33:47 -0500 (EST)
- References: <hcjisk$jld$1@smc.vnet.net> <hconks$1e7$1@smc.vnet.net>
First, thanks to Armand/Mike for his suggestion. It gets me a long way
to what I need. The other suggestions to use add-on products are
well-taken, but aren't likely to be accepted by my employer. Thanks
anyway.
On 2009-11-03 18:55:08 +1100, Armand Tamzarian
<mike.honeychurch at gmail.com> said:
> On Nov 1, 3:03 am, Luci Ellis <l... at verbeia.com> wrote:
>>
>> Can anyone offer any guidance on placement of ticks in BarChart, and
>> combining them with DateListPlots? Or, failing that, making
>> DateListPlots look like BarCharts?
>>
>> Thanks in advance,
>> Luci
>
> This requiring some further work but seems to do what you want.
>
> Make some sample data ...I guess it might come in this sort of format
>
> someData = Flatten[Table[{ToString[i] <> "q" <> ToString[j], RandomRe=
al
> [{-10, 10}]}, {i, 1999, 2008}, {j, 1, 4}], 1];
>
> You will be able to convert it to this format easily enough:
>
> data1 = Flatten[Table[{{i, j}, RandomReal[{-5, 5}]}, {i, 1999, 2008},
> {j, 1, 4}], 1];
> data2 = Flatten[Table[{{i, j*3}, RandomReal[{8, 20}]}, {i, 1999,
> 2008}, {j, 1, 4}],1];
>
> (* need to tweek this for leap years *)
Create the daily dates as a flat list, then use GatherBy?
>
> dates[{year_, quarter_}] := Which[
> quarter == 1, DatePlus[{year, 1, 0}, #] & /@ Range[90],
> quarter == 2, DatePlus[{year, 4, 0}, #] & /@ Range[91],
> quarter == 3, DatePlus[{year, 7, 0}, #] & /@ Range[92],
> quarter == 4, DatePlus[{year, 10, 0}, #] & /@ Range[92]
> ];
>
> barData = Thread[{dates[#[[1]]], #[[2]]}] & /@ data1;
>
> p1 = DateListPlot[barData, Joined -> False, Filling -> 0];
> p1 = DeleteCases[p1, _Point, \[Infinity]];
> p2 = DateListPlot[data2, Joined -> True, PlotStyle -> Thick];
>
> Show[p2, p1, PlotRange -> All]
This is a very helpful clue, thanks. In fact, as long as you are only
exporting graphics to PDF, GIF, PNG etc, there is no need to
DeleteCases the Points. This works:
DateListPlot[{barData1, barData1a}, PlotStyle -> Directive[Opacity[0]],
=E2=80=A8 Filling -> {1 -> {0, Blue}, 2 -> {{1}, Red}}]
(try this for barData1 = Flatten[Most /@ barData, 1]; and
data1a = {0, 1.*Sign[#[[2]]]} + # & /@ data1
barData1a = Flatten[Most /@ (Thread[{dates[#[[1]]], #[[2]]}] & /@
data1a), 1]; )
It's not even necessary to create two plots and use Show.
But it is incredibly slow (creating daily data out of non-daily data),
and will only work for stacked bars (see below) not side by side bars,
unless one fakes the date positions for the second series.
i will keep working on it. In the meantime, any other suggestions are
greatly appreciated.
> I don't know how to get the year labels centred. Maybe someone else
> can offer a suggestion.
This bit I already have working -- just not TickPlacement in BarChart.
It involves AdjustmentBox constructs like this.
RBADateTicks[min_, max_, opts___Rule] :==E2=80=A8 Module[{seq},=E2=80=A8=
With[{dateformat = DateLabelFormat /. {opts} /. Options[RBADateTicks],=E2=
=80=A8
datelabelspacing = DateLabelSpacing /. {opts} /.
Options[RBADateTicks],=E2=80=A8 vertshift = DateLabelVerticalShift /=
. {opts}
/. Options[RBADateTicks],=E2=80=A8 afac = With[{afacopt = DateLabe=
lOffset /.
{opts} /. Options[RBADateTicks]},=E2=80=A8 Switch[afacopt, Automati=
c, =E2=80=A8
AutoDateLabelOffset[max - min + 1], _?NumericQ, afacopt]]},=E2=80=A8 =
seq
= If[datelabelspacing == Automatic, AutoDateLabel[max - min + 1], =E2=
=80=A8
datelabelspacing];=E2=80=A8 Table[{{i, 1, 1}, =E2=80=A8 If[Mod[max =
- i, seq] ==
0, =E2=80=A8 DisplayForm[=E2=80=A8 AdjustmentBox[DateString[{i=
, 1, 1},
{dateformat}], =E2=80=A8 BoxBaselineShift -> 0.1, BoxMargins -> {{=
afac,
0}, {0, 0}}]], =E2=80=A8 ""], {0.015, 0}}, {i, Range[min, max]}]=E2=80=
=A8 ]]
where
AutoDateLabelOffset[num_Integer?Positive] := =E2=80=A8 Switch[num, 1, 3=
2, 2,
16, 3, 10.5,=E2=80=A8 4, 8.,=E2=80=A8 5, 6.8,=E2=80=A8 6, 5.2, 7, 4.7,=
8, 4.0, 9, 3.7, 10,
3.5, 11, 3.25, 12, 2.9, 13, 2.65, 14, =E2=80=A8 2.35, 15, 2.3, 16, 2.15,=
17,
2.05, 18, 2., 19, 1.9, 20, 1.8, _, 1.5]
and
AutoDateLabel[num_Integer?Positive] := =E2=80=A8 Piecewise[{{1, num < 6=
}, {2, 5
<= num <= 10}, {3, 10 < num <= 15}, {4, =E2=80=A8 15 < num < 20}=
, {5, 20 <=
num <= 45}, {10, num > 45}}, 5]=E2=80=A8