# ParetoPlot change category orientation

The very useful ParetoPlot sometimes needs the ChartLabels rotated. I have not been able to find a convenient method of doing it.

data = {"a very long name", "a very long name", "short", "short",
"a very long name","a very long name", "a very long name",
"a", "b", "c", "d", "e"};
ParetoPlot[data]


As you can see the label "a very long name" overlaps with the next bin.

I want to rotate the labels but have not found a convenient method and find it difficult to imagine that an option does not allow for this maybe using ChartLabels. The method I have so far is

ParetoPlot[data,
ChartLabels -> (Rotate[#, Pi/2] & /@ {"a very long name", "short",
"a", "b", "c", "d", "e"})]


which is obviously an incorrect method because the labels would be in the incorrect order.

A solution would be appreciated.

• I do not think the order is incorrect. Any permutation of {"a", "b", "c", "d", "e"} is correct, since the categorical variable counts are all the same (1). Feb 10, 2017 at 14:41
• @AntonAntonov Though its interesting why the function changes the order provided. If you use the form ParetoPlot[{{"a very long name", 5}, {"short", 2}, {"a", 1}, {"b", 1}, {"c", 1}, {"d", 1}, {"e", 1}}], the equal categories are rearranged such that e is the first and a is the last. Feb 10, 2017 at 14:55
• @ercegovac See my answer, which is more of an extended reply to your comment. Feb 10, 2017 at 15:16

It seems that what is given to CharLabels is imposed on the bars of the Pareto plot. Meaning, the order of the labels should correspond to the Pareto order.

For example this appears wrong, but we can argue that it is a desired outcome.

ParetoPlot[{{"a very long name", 5}, {"short", 2}, {"a", 1.01}, {"b",
1.008}, {"c", 1.007}, {"d", 1.006}, {"e", 1.5}},
ChartLabels -> (Rotate[#, Pi/2] & /@ {"a very long name", "short",
"a", "b", "c", "d", "e"})]


A work-around is to use pre-sorted data (in Pareto order.)

talliedData =
SortBy[{{"a very long name", 5}, {"short", 2}, {"a", 1.01}, {"b",
1.008}, {"c", 1.007}, {"d", 1.006}, {"e", 1.011}}, -#[[2]] &];
ParetoPlot[talliedData,
ChartLabels -> (Rotate[#, Pi/2] & /@ talliedData[[All, 1]])]


(Note that this makes the whole plot specification much longer, which is not what OP wants.)

• But you changed values of the elements here. ParetoPlot[list] creates a Pareto plot from the frequencies of the elements in list (from Help). The numbers I gave correspond to the frequency of the occurrence of the elements in the original data. One would expect that given the same frequency of occurrence, they will bi plotted in the order in which they appear in the argument. Or not? Feb 10, 2017 at 15:26
• @ercegovac The workaround should work in the frequency case. I changed the values only to provide an illustrative example of what is the perceived bug/feature. Feb 10, 2017 at 15:54

Thank you for your inputs. I have a ParetoPlot function which adds an optional function ChartLabelsStyle. I notice however that the labels are double printed.

Options[myParetoPlot] = Join[{ChartLabelsStyle -> Function[#]}, Options[ParetoPlot]];
myParetoPlot[data_List, opts : OptionsPattern[]] := Module[{talliedData, style, ppopts},
talliedData = If[MatchQ[data, {{_, _?NumericQ} ..}], data, Tally[data]];
talliedData = SortBy[talliedData, -Last[#] &];
style = OptionValue[myParetoPlot, ChartLabelsStyle];
ppopts = Apply[Sequence, FilterRules[{opts}, Options[ParetoPlot]]];
ParetoPlot[talliedData, ppopts, ChartLabels -> Map[style, talliedData[[All, 1]]]]];

myParetoPlot[data, ChartLabelsStyle -> Function[Rotate[#, Pi/2.5]], Frame -> True]


So note double imaged labels and the unfortunate position of the labels where it is normal for the top of the labels to be at the centre of the mark rather than the centre of the label being at the centre of the mark. It would be nice to fix that final problem.