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