Background
I have been working with a set of data for some time now and I recently decided to change the format. The data is a tree-styled listing of hierarchical names and positions.
(* Names have been removed. *)
My goal is to take the tree and convert it into a different form, something like one of these:
(* Once again, name has been removed from Tooltip *)
I am currently doing this with the Disk[]
primitive, but this requires me to build it up from the ground (outside) instead of the top (inside) so that they stack properly and the inner layers are visible.
The Question
The PieChart[]
method built into Mathematica provides an option for removing a portion of the chart (the annulus of the circle) using SectorOrigin->{{pos,sense}, r_inner}
. Unfortunately the Disk
primitive does not have the same ability (as far as I can tell...) so I looked at the full code for the creation of a simple donut chart:
PieChart[{1,1}, SectorOrigin->{Automatic,1}]//FullForm
The full form code explains that the PieChart creates the sectors as point listed polygons instead of as something a little more simple.
Is there a better way to go about removing the center portion of a Disk[]
without generating a list of points and joining them as a polygon? I ask this question because it seems that this should be an option for Disk[]
and I'm curious to know if I have missed something. The end result should allow me to generate the sectors of the Sunburst Chart above without having to pay attention to the order in which it was generated (no centers means the chart wouldn't require a certain stacking order).
Also
As a side note : I considered using Circle
with the Thickness
option:
Graphics[{Thickness[0.05],Circle[{0,0},1,{0,Pi}]}]
but the generated output is not partitioned properly and gives more of a U shape than a pie sector.
A module I used when coming up with the idea
Unfortunately the data does not have even divisions, so the model represented here isn't good for the data (nor does it use the data to create the chart), but it may help you understand how I stumbled onto the question. I can't seem to believe that Mathematica doesn't have that option built in to one of the primitives
Manipulate[ Module[ {makeDisk, tree, partitions, color, range},
range = {lowerlim, upperlim, upperlim - lowerlim};
(* Plotting Colors *)
color = {RGBColor[32/255, 0/255, 64/255], RGBColor[64/255, 0/255, 127/255], RGBColor[128/255, 0/255, 255/255], RGBColor[96/255, 0, 191/255], RGBColor[115/255, 0/255, 229/255]};
(* Applying colors 1 - top level, 2,3 - even levels, 4,5 - odd levels *)
colorApplied[level_, division_] := If[level != 1, If[EvenQ[level], If[EvenQ[division], color[[2]], color[[3]]], If[EvenQ[division], color[[4]], color[[5]]]], color[[1]]];
(* Function to make disks *)
makeDisk[level_, divisions_] := Module[{fan},
partitions = divisions^(level - 1);
fan = Table[{EdgeForm[Thick], colorApplied[level, i], Disk[{0, 0},level,lowerlim + Partition[Table[(n*range[[3]])/partitions, {n, 0, partitions}], 2, 1][[i]]]},{i, 1, partitions}];
Return[fan]
];
(* Tree Construction *)
tree = Append[Drop[Table[makeDisk[(levels - level + 1), divisions], {level, 1, levels}], -1], {EdgeForm[Thick], color[[1]], Disk[{0, 0}, 1, {lowerlim, upperlim}]}];
(* Display Graphic *)
Show[Graphics[tree]]
],
(* Manipulate components *)
{{levels, 2, "Depth"}, 2, 15, 1},
{{divisions, 2, "Subgroups"}, 2, 10, 1},
{{lowerlim, 0, "Bound1"}, 0, (upperlim - Pi/6), Pi/6},
{{upperlim, 2 Pi, "Bound2"}, (lowerlim + Pi/6), 2 Pi, Pi/6},
TrackedSymbols :> Manipulate
]
Using Polygon to create a Graphic Primitive
Yes, I could create a polygon primitive to generate the ring...
ring[outter_, inner_, size_, res_] :=
Module[{p, q, outterPoints, innerPoints, partition},
p = res;
q = (size)/(2 Pi);
outterPoints =
Table[{outter Cos[ k q 2 Pi/p], outter Sin[ k q 2 Pi/p]}, {k, 1,
p}];
innerPoints =
Table[{inner Cos[ k q 2 Pi/p], inner Sin[ k q 2 Pi/p]}, {k, 1, p}];
partition =
Polygon[Flatten[{outterPoints, Reverse@innerPoints}, 1]];
Return[partition]
];
Then running using this, or something similar.
Graphics[ring[2, 1, Pi/2, 3000]]
to generate this:
Then I could either rotate or change the primitive for the specific positioning, but I'd prefer if there were some way to do it based on the built-in functions of Mathematica.