Re: DateListBarChart / Ticks in BarChart
- To: mathgroup at smc.vnet.net
- Subject: [mg104628] Re: DateListBarChart / Ticks in BarChart
- From: Luci Ellis <luci at verbeia.com>
- Date: Thu, 5 Nov 2009 03:50:22 -0500 (EST)
- References: <hcjisk$jld$1@smc.vnet.net> <hconks$1e7$1@smc.vnet.net> <hcr79i$8cr$1@smc.vnet.net>
An update: This seems to work nicely in DateListPlot: Epilog -> ({ Blue, =E2=80=A8 Rectangle[Offset[{-.2, 0}, {#[[1]], 0}], Offset[{1.1, 0}, #]] & /@ =E2=80=A8 data]}) (where the data are in the form {{1999,12,1},number}..} ) The exact amount of offset depends on the number of bars, but this is not a big issue. Stacked bars will need MapThread or something, presumably. This solution also renders much faster than Mike's. I hope it is useful to others. Regards, Luci On 2009-11-04 17:34:26 +1100, Luci Ellis <luci at verbeia.com> said: > 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], RandomReal >> [{-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 = DateLabelVertica= lShift /= > . {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, BoxMargi= ns -> {{= > afac, > 0}, {0, 0}}]], =E2=80=A8 ""], {0.015, 0}}, {i, Range[min, ma= x]}]=E2=80= > =A8 ]] > > where > > AutoDateLabelOffset[num_Integer?Positive] := =E2=80=A8 Switch[n= um, 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, 1= 6, 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 < n= um < 20}= > , {5, 20 <= > num <= 45}, {10, num > 45}}, 5]=E2=80=A8