# How can I tell mathematica to generate an histogram from nominal data?

If I write:

Histogram[{1, 1, 1, 2, 2, 2}]


I get a nice histogram chart

but if I write

Histogram[{"A", "A", "A", "B", "B", "B"}]


I get an empty chart!!

How can I tell mathematica to generate an histogram from nominal data?

Perhaps like this:

data = {"A", "A", "B", "B", "B"};

elements = DeleteDuplicates[data];

rep = MapIndexed[# -> #2[[1]] &, elements];

Histogram[data /. rep, ChartStyle -> "Pastel",
ChartLegends -> elements]


EDIT: Incorporating @Simon Wood´s splendid suggestion (we learn that the legend is a plain Column, which should be considered a good thing):

Bigger sorted input with monster legend. Notice: Bin widths other than one mess this up somewhat...

data = RandomChoice[CharacterRange["A", "Z"], 1000] // Sort;
elements = DeleteDuplicates[data];
rep = MapIndexed[# -> #2[[1]] &, elements];

Histogram[data /. rep, Length[elements], ChartStyle -> "Pastel",
ChartLegends -> Placed[elements, Right]] /.
Column[x_] :> Grid[Partition[x, 4, 4, {1, 1}, {}]]


And now for some fun:

data = Characters[ExampleData[{"Text", "FaustI"}]] // Sort;
elements = DeleteDuplicates[data];
rep = MapIndexed[# -> #2[[1]] &, elements];

Histogram[data /. rep, Length[elements], ChartStyle -> "Pastel",
ChartLegends -> Placed[elements, Right]] /.
Column[x_] :> Grid[Partition[x, 8, 8, {1, 1}, {}]]


ToDo: modify the ticks accordingly.

• For the legend try Histogram[...] /. Column[x_] :> Grid[Partition[x, 4, 4, {1, 1}, {}]] Aug 24, 2012 at 8:48

One posibility is to use Tally with BarChart.

For example:

hist = Tally[{"A", "A", "B", "B", "B"}];
BarChart[hist[[All, 2]], ChartLabels -> hist[[All, 1]]]


Here is a variation that works with multiple data sets:

BarChart: pure categorical variables

 ClearAll[mapCount]
mapCount[dataset_] :=
Map[Function[{elem}, {elem, Count[#, elem]}], Union @@ dataset] & /@ dataset

data2 = {{"A", "A", "B", "B", "B"}, {"A", "A", "A", "A", "B","B"},
{"A", "A", "C", "C", "C", "B"}};
bcdatasets = Last /@ # & /@ mapCount[data2];
bclabels = Union @@ data2;
BarChart[bcdatasets, ChartLabels -> bclabels]


Alternatively, you can use Tally on the sorted data sets with Padright:

BarChart[Last /@ # & /@ PadRight[Tally /@ Sort /@ data2], ChartLabels -> bclabels]


gives the same result.

Histogram: ordered categorical variables:

histdata = ArrayComponents[data2];
histlabels = MapIndexed[{First@#2 + .5, #1} &, Union @@ data2];

Column[Row[{Histogram[histdata, Automatic, #,
Ticks -> {histlabels, Automatic},
ChartLayout -> "Overlapped", PlotLabel -> # <> " - Overlapped",
ImageSize -> 200], Spacer[15],
Histogram[histdata, Automatic, #,
Ticks -> {histlabels, Automatic},
ChartLayout -> "Stacked", PlotLabel -> # <> " - Stacked",
ImageSize -> 200]}] & /@
{"Count", "Probability", "PDF", "CumulativeCount", "CDF", "SF"}]