20
$\begingroup$

Can we make a pie chart using a custom picture?

For example, consider this image of one cent coin:

enter image description here

I would like to use this image and cut pieces out, depending on data, and also make a clickable pie chart. Any suggestions are appreciated.

$\endgroup$
27
$\begingroup$
i = Import@"http://i.stack.imgur.com/8I3B1.jpg";
f[{{tmin_, tmax_}, {rmin_, rmax_}}, ___] :=
 Module[{l = Join[{{0, 0}}, Table[{Cos@t, Sin@t}, {t, tmin, tmax, (tmax-tmin)/100}]]},
  {Texture[i], EdgeForm[],
   Polygon[l, VertexTextureCoordinates -> 1/2 Transpose[Transpose[l] + {1, 1}]]}]

Framed@PieChart[{1, 2, 3, 4, 5, 6}, ChartElementFunction -> f]

Mathematica graphics

Edit

You may also want to get a better visual feedback:

Module[{cd = ColorData[3, "ColorList"]},
 f[{{tmin_, tmax_}, {rmin_, rmax_}}, ___] := 
  Module[{l = Join[{{0, 0}}, Table[{Cos@t, Sin@t}, {t, tmin, tmax, (tmax - tmin)/100}]]},
   cd = RotateLeft@cd;
   {Texture[ImageCompose[i, {Graphics[{cd[[1]], Disk[]}], 0.5}]], EdgeForm[], 
     Polygon[l, VertexTextureCoordinates -> 1/2 Transpose[Transpose[l] + {1, 1}]]}]
 ]

Framed@PieChart[{1, 2, 3, 4, 5, 6}, ChartElementFunction -> f]

Mathematica graphics

$\endgroup$
14
$\begingroup$

Combinining @belisarius's cool solution for the key challenge with some built-in ChartElementDataFunctions you can do a number of tricks:

onecent=Import["http://i.stack.imgur.com/8I3B1.jpg"];
ClearAll[cEDF];
cEDF[datafunc_: ChartElementDataFunction["NoiseSector",
     "AngularFrequency" -> 13, "RadialAmplitude" -> 0.1]][texture_:
       ExampleData[{"TestImage", "Mandrill"}]][{{t0_, t1_}, {r0_, r1_}}, y_, z___] := 
(datafunc[{{t0, t1}, {r0, r1}}, y , z] /. 
  Polygon[a_, b___] :> Sequence[Texture[texture], 
   Polygon[a, VertexTextureCoordinates -> 
   1/2 Transpose[Transpose[a/(r1 + 2 ("RadialAmplitude" /. Options[datafunc]))] + {1,1}]]]);


noiseF = ChartElementDataFunction["NoiseSector", 
        "AngularFrequency" -> 13, "RadialAmplitude" -> 0.1]; 
oscltngF =  ChartElementDataFunction["OscillatingSector", 
       "AngularFrequency" -> 6, "RadialAmplitude" -> 0.21`]; 
sqrwvF =  ChartElementDataFunction["SquareWaveSector", 
     "AngularFrequency" -> 50, "RadialAmplitude" -> 0.1`];
trnglwvF =   ChartElementDataFunction["TriangleWaveSector", 
     "AngularFrequency" -> 18, "RadialAmplitude" -> 0.1`];


Row[PieChart[{{2, 2, 3, 4}}, ChartElementFunction -> cEDF[#][onecent], 
     SectorOrigin -> {Automatic, .5}, ImageSize -> 300] & /@ 
    {noiseF, oscltngF, sqrwvF, trnglwvF}, Spacer[5]]

enter image description here

 Row[PieChart[{{2, 2, 3, 4}}, ChartElementFunction -> cEDF[#][], 
   SectorOrigin -> {Automatic, .5}, ImageSize -> 300] & /@ 
     {noiseF, oscltngF, sqrwvF, trnglwvF}, Spacer[5]]

enter image description here

Update: Combining with ChartStyle colors:

cEDF2[datafunc_: ChartElementDataFunction["NoiseSector",
     "AngularFrequency" -> 13, "RadialAmplitude" -> 0.1]][texture_:
       ExampleData[{"TestImage", "Mandrill"}]][{{t0_, t1_}, {r0_, r1_}}, y_, z___] :=
  (datafunc[{{t0, t1}, {r0, r1}}, y, z] /. Polygon[a_, b___] :>
     Sequence[Dynamic@Texture[ImageMultiply[texture, CurrentValue["Color"]]], 
  Polygon[a,  VertexTextureCoordinates -> 1/2 
    Transpose[Transpose[a/(r1 + 2 ("RadialAmplitude" /. Options[datafunc]))] + {1,1}]]]);


Row[PieChart[{{2, 2, 3, 4}}, ChartElementFunction -> cEDF2[#][onecent],
   SectorOrigin -> {Automatic, .2},ImageSize -> 300,
   ChartStyle -> (Directive[Opacity[.9], #] & /@Rest[ColorData[3, "ColorList"]])] & /@
     {noiseF, 
      oscltngF /.HoldPattern["AngularFrequency" -> _] :> "AngularFrequency" -> 9,
      sqrwvF /.HoldPattern["AngularFrequency" -> _] :> "AngularFrequency" -> 15,
      trnglwvF}, Spacer[5]]

enter image description here

$\endgroup$
  • 4
    $\begingroup$ (+1) However, if anyone presented me with a pie chart like that, I'd seriously doubt their data (among other things). Unless you call the coin pie chart "Change you can believe in!" $\endgroup$ – Jens May 19 '14 at 1:24
  • 2
    $\begingroup$ @Jens, this is meant to be primarily used for presenting questionable data :) $\endgroup$ – kglr May 19 '14 at 1:27
5
$\begingroup$

Here is a simple 3d version modified from belisarius's answer, by just stacking many layers of polygons together.

i = Import@"http://i.stack.imgur.com/8I3B1.jpg";
f3d[{{tmin_, tmax_}, {rmin_, rmax_}, {hmin_, hmax_}}, ___] := 
 Module[{l = Join[{{0, 0}}, Table[{Cos@t, Sin@t}, {t, tmin, tmax, (tmax - tmin)/100}]]}, 
  Table[{Texture[i], EdgeForm[], Polygon[Append[#, n] & /@ l, 
     VertexTextureCoordinates -> 1/2 Transpose[Transpose[Append[#, n] & /@ l] + {1, 1, 1}]]}, 
  {n,0., 1.0, 0.05}]]
PieChart3D[{1, 2, 3}, ChartElementFunction -> f3d]

enter image description here

$\endgroup$
  • $\begingroup$ You may also make it "solid" by using Append[If[n == 1, #, {0, 0}], n]. The grainy edge is lost, though $\endgroup$ – Dr. belisarius May 19 '14 at 18:23

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.