21
$\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$
0

3 Answers 3

28
$\begingroup$
i = Import@"https://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$
0
16
$\begingroup$

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

onecent=Import["https://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$
2
  • 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, 2014 at 1:24
  • 2
    $\begingroup$ @Jens, this is meant to be primarily used for presenting questionable data :) $\endgroup$
    – kglr
    May 19, 2014 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@"https://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$
1
  • $\begingroup$ You may also make it "solid" by using Append[If[n == 1, #, {0, 0}], n]. The grainy edge is lost, though $\endgroup$ May 19, 2014 at 18:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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