3
$\begingroup$

How can I automatically create a Disk with a certain number of segments that are differently colored automatically depending on some values I input? For example, I want a disk with seven segments of a certain size, e.g. the First segment is 40 % starting and ending at some specified angle, the second one is 40 % asf. So basically I just want to input my percentages and the colors and then the disc is created. This is similar to what PieChart does, but I want to choose the position where a segment appears manually and it should be a graphics object.

I got as far as adjusting each of the segment in an awkwardly tedious way by manually finding the right values, but got stuck finding the right values automatically based on percentages.

innerDiskSize = 1
disk = {Orange, Disk[{0, 0}, innerDiskSize, {0.007, Pi/1.77}], 
  Magenta, Disk[{0, 0}, innerDiskSize, {Pi/1.77, 7.15 Pi/7}] , Red, 
  Disk[{0, 0}, innerDiskSize, {7.15 Pi/7, 9.38 Pi/7}], Blue, 
  Disk[{0, 0}, innerDiskSize, {9.38 Pi/7, 10.12 Pi/7}], Yellow, 
  Disk[{0, 0}, innerDiskSize, {10.12 Pi/7, 10.95 Pi/7}], Brown, 
  Disk[{0, 0}, innerDiskSize, {10.95 Pi/7, 11.85 Pi/7}] , Cyan, 
  Disk[{0, 0}, innerDiskSize, {11.85 Pi/7, 14.03 Pi/7}]   }
Graphics[disk]

Any help appreciated!

$\endgroup$
  • $\begingroup$ Isn't this what PieChart does $\endgroup$ – Coolwater Aug 13 '17 at 10:38
  • $\begingroup$ Yes you are right, but I want to choose the positions of the segments manually $\endgroup$ – holistic Aug 13 '17 at 10:53
  • 3
    $\begingroup$ PieChart has the option SectorOrigin $\endgroup$ – Coolwater Aug 13 '17 at 10:56
  • $\begingroup$ Yes, PieChart can do this, but it needs to be a Graphics object! $\endgroup$ – holistic Aug 13 '17 at 13:20
  • $\begingroup$ Doesn't Head[PieChart[your input]] return Graphics? $\endgroup$ – Coolwater Aug 13 '17 at 13:56
7
$\begingroup$

I don't know, why PieChart wouldn't help you here. To create a 40%, 30%, 20%, 10% pie, just use

PieChart[{.4, .3, .2, .1}, SectorOrigin -> {0, 0}, PerformanceGoal -> "Speed"]

Mathematica graphics

The option PerformanceGoal->"Speed" ensures that you get a pure Graphics without any dynamic annotations. SectorOrigin helps to position make your sectors start wherever you want.

If you like to colour the sectors, use the ChartStyle option.

$\endgroup$
  • $\begingroup$ Thanks for the answer, but I need to embed the PieChart in a more complex Graphics object. But I figured out that I can use Inset to embed it: Graphics[{Disk[{0, 0}, 5], Inset[PieChart[{.4, .3, .2, .1}, SectorOrigin -> {0, 0}, PerformanceGoal -> "Speed"], {0, 0}, {0, 0}, 11]}] $\endgroup$ – holistic Aug 13 '17 at 17:00
  • 1
    $\begingroup$ As I said, when you use PerformanceGoal->"Speed", you get an ordinary Graphics object. So you could use for instance pie[[1]] to extract the graphics primitives and combine them inside another graphics without using inset. $\endgroup$ – halirutan Aug 13 '17 at 19:38
  • $\begingroup$ Ah, I understand now, thank you! $\endgroup$ – holistic Aug 13 '17 at 19:58
3
$\begingroup$

I have at times been quite disappointed with the performance of plotting functions, e.g. Why is ListPlot so slow here? and I have long advocated manual Graphics constructs for performance, flexibility, and reliability. Here therefore is an alternative to PieChart.

pie[
  v_?VectorQ,
  scheme_,
  ori : _?NumericQ : 0,
  opts : OptionsPattern[Graphics]
] :=
  Module[{spec, colorfn, secfn, i = 1},

    colorfn = ColorData[{scheme, {1, Length@v}}];
    secfn = {colorfn[i++], Disk[{0, 0}, 1, #]} &;
    spec = Partition[Accumulate @ Prepend[2` Pi v/Tr[v], ori], 2, 1];

    Graphics[{EdgeForm[Opacity[0.5, Black]], secfn /@ spec, Circle[]}, opts]

  ]

pie[{3, 1, 4, 1, 5, 9}, "CandyColors", Pi/2]

enter image description here

And a performance comparison:

SeedRandom[0];
dat = RandomReal[1, 700];

pie[dat, "CandyColors", Pi/2] // RepeatedTiming // First

PieChart[dat, ChartStyle -> "CandyColors", SectorOrigin -> Pi/2, 
   PerformanceGoal -> "Speed"] // RepeatedTiming // First
0.0029

0.74

More than two orders of magnitude faster than PieChart despite specifying PerformanceGoal -> "Speed". Not bad, if I do say so myself. :^)

$\endgroup$
  • $\begingroup$ Thank you! Very sophisticated solution ;). $\endgroup$ – holistic Aug 16 '17 at 17:47
1
$\begingroup$

By now, I found a solution by using Insetin order to embed the PieChart into a Graphics object:

Graphics[{Disk[{0, 0}, 7], 
  Inset[PieChart[{.4, .3, .2, .1}, SectorOrigin -> {0, 0}, 
    PerformanceGoal -> "Speed", ImageSize -> 100], {0, 0}, {0, 0}, 
   Automatic]}] 

What I didn't figure out yet, is how to adjust the size of the Inset such that it has the same radius as the disk. Does anyone have an idea how to do this?

$\endgroup$
  • 1
    $\begingroup$ Use Inset[Show[PieChart[{.4, .3, .2, .1}, SectorOrigin -> {0, 0}, PerformanceGoal -> "Speed"], PlotRangePadding -> None], {0, 0}, {0, 0}, diameter] $\endgroup$ – Coolwater Aug 13 '17 at 17:44
  • $\begingroup$ I see, thanks a bunch! $\endgroup$ – holistic Aug 13 '17 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.