5
$\begingroup$

Description:

I would like to enforce consistent legend and style throughout dynamic PieChart evaluation.

Problem:

Based on current implementation, the color and legend associated with particular datasets switch throughout evaluation.

Example:

DynamicModule[
 {n = 20},
 Column[{
   Row[{Slider[Dynamic[n], {1, 100, 1}], Dynamic[n]}],
   Dynamic[
    PieChart[#[[All, 2]], ChartLegends -> #[[All, 1]], 
       ChartStyle -> {Green, Red}] & @ 
     Tally @RandomChoice[{True, False}, n]]
   }]
 ]

Output:

output1
output2
output3

How could I enforce Legend to include both True and False; where True to be always represented in Green and False in Red? I would also like True to come before False in the Legend.

$\endgroup$
  • 1
    $\begingroup$ If you do Sort@Tally@RandomChoice... it'll sort the values first and won't have this problem. $\endgroup$ – N.J.Evans May 26 '16 at 16:02
  • $\begingroup$ @N.J.Evans partially, it does. There is however another issue which is related to the question. Please let me edit OP. $\endgroup$ – e.doroskevic May 26 '16 at 16:05
  • $\begingroup$ Use trueFalseTally[list_] := {#, Count[list, #]} & /@ {True, False}; instead of Tally It will return {{True,numTrues},{False,numFalses}}` even if there aren't any, then your plot will format correctly. $\endgroup$ – N.J.Evans May 26 '16 at 16:23
  • $\begingroup$ @N.J.Evans Appreciate that, leave your answer. I will leave the question open for some time to see what people think. If there is no other solutions, I will be happy to accept your answer $\endgroup$ – e.doroskevic May 26 '16 at 16:28
5
$\begingroup$
DynamicModule[{n = 20}, 
 Column[{Row[{Slider[Dynamic[n], {1, 100, 1}], Dynamic[n]}], 
   Dynamic[Legended[PieChart[Thread[Style[#[[All, 2]], #[[All, 1]] /.
        {True -> Red, False -> Green}] ], 
      ChartStyle -> {Green, Red}] &@ 
      Tally@RandomChoice[{True, False}, n], 
     SwatchLegend[{Green, Red}, {False, True}]]]}]]

Mathematica graphics

Mathematica graphics

Alternatively (thanks: Brett Champion):

DynamicModule[{n = 20}, 
 Column[{Row[{Slider[Dynamic[n], {1, 100, 1}], Dynamic[n]}], 
   Dynamic[PieChart[Thread[Style[#[[All, 2]], #[[All, 1]] /. 
                      {True -> Red, False -> Green}]], 
       ChartLegends -> SwatchLegend[{Green, Red}, {False, True}]] &@
     Tally@RandomChoice[{True, False}, n]]}]]
$\endgroup$
  • 2
    $\begingroup$ You can also pass the SwatchLegend to ChartLegends: ChartLegends -> SwatchLegend[{Green, Red}, {True, False}] $\endgroup$ – Brett Champion May 26 '16 at 18:49
  • $\begingroup$ This fails in the case that n=1 and RandomChoice returns True. Since Tally only returns an entry for True, your ChartStyle applies Green to the True value, even though the legend is correct. $\endgroup$ – N.J.Evans May 26 '16 at 19:28
  • $\begingroup$ I think all the code should be checked carefully as to whether green is true or false... $\endgroup$ – Brett Champion May 26 '16 at 19:30
  • $\begingroup$ @N.J.Evans, thank you. I will update with a fix. $\endgroup$ – kglr May 26 '16 at 19:40
  • $\begingroup$ @Brett and N.J. Evans, thank you for the comments. I hope the updated version fixes the issue you mention. $\endgroup$ – kglr May 26 '16 at 19:51
4
$\begingroup$

The Red/Green problem stems from the fact that Tally returns tallied values in the order each element is first encountered, and the other issue is because Tally doesn't return a 0 entry for elements not in the list. Both issues can be solved with a custom tally:

explicitTally[list_,toTally_List] := {#, Count[list, #]} & /@ toTally;

If you use explicitTally[#,{True,False}] in place of Tally everything should work correctly. Use is shown below, I also used Transpose and Apply (@@) to clean it up a little.

DynamicModule[
 {n = 20},
 Column[{
   Row[{
     Slider[Dynamic[n], {1, 100, 1}],
     Dynamic[n]
     }],
   Dynamic[
    PieChart[
       #2,
       ChartLegends -> #1,
       ChartStyle -> {Green, Red}
       ] & @@ 
     Transpose@
      explicitTally[RandomChoice[{True, False}, n], {True, False}]
    ]
   }]
 ]
$\endgroup$

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.