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?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityIf 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.
Histogram[...] /. Column[x_] :> Grid[Partition[x, 4, 4, {1, 1}, {}]]
$\endgroup$
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"}]