# ListPlot with lots of same couples of values

In my dataset of (x,y) values I have a lot of points with the exact same values on x and y: {{1,2},{3,4},{3,4},{3,4},{4,5}}

So when I plot them with ListPlot it looks like I have only one point for {3,4}, which doesn't help me assess the real distribution of my data.

What would be the best way to get a better sense of the distribution visually, to know that behind a single point are in fact hidden lots of other points?

try this also:

t = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}, {3, 4}, {1, 2}, {6, 7}};

ListPlot[Labeled[Style[#1, PointSize[#2/50], Hue[#2/10]],
Style[#2, Bold, 12]] & @@@ (Tally[t])]


• If you make it PointSize[Sqrt[#2]/50] then the area of the dots will be proportional to the tally, which seems more appropriate.
– user484
Sep 22, 2014 at 4:30
• @RahulNarain Ok. Thanks. Sep 22, 2014 at 12:59

I suggest two more approaches in addition to the ones proposed in other answers:

Arrange duplicates on a circle:

Inspired by Rahul's jittering idea, you can also arrange the duplicates in a more regular fashion -- e.g., on a circle around their common center:

ClearAll[coordsF];
coordsF[sc_:.2] := Table[# + If[#2 === 1, 0, sc {Sin[2 Pi k /#2], Cos[2 Pi k /#2]}],
{k, #2}] &;

t = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}};
tb = RandomInteger[{1, 7}, {50, 2}];

ListPlot[coordsF[] @@@ Tally[t],
BaseStyle -> PointSize[.03], Frame -> True, PlotStyle -> "SolarColors",
Prolog -> {Opacity[.5], Blue, Thick, Line[t],
EdgeForm[{Opacity[.5], Blue, Thick}],
FaceForm[{Opacity[1], LightBlue}], Disk[#, .35] & /@ t},
AxesOrigin -> {0, 0}, PlotRange -> {{0, 6}, {0, 6}}, AspectRatio -> 1]


ListPlot[coordsF[] @@@ Tally[tb],
BaseStyle -> PointSize[.03], Frame -> True, PlotStyle -> "SolarColors",
Prolog -> {Blue, Opacity[.5], Line@tb, Yellow, Opacity[.5],  Disk[#, .3] & /@ tb},
AspectRatio -> 1, PlotRangePadding -> .5,  AxesOrigin -> {0, 0}]


BubbleChart:

BubbleChart with its many features and options is a natural tool for this kind of data. You can use Prolog or Epilog to add a line if you need to join the points.

BubbleChart[Append @@@ Tally[t], ChartStyle -> 63,
ChartLabels -> (Style[#, # 10, Bold] & /@ Tally[t][[All, -1]]),
Prolog -> {Thick, Blue, Line[t]}, PlotRange -> {{0, 6}, {0, 6}}]


BubbleChart with a custom ChartElementFunction:

The following custom ChartElementFunction produces a PieChart with equal divisions.

ceF[sc_: .03, style_: 24][c : {{xmin_, xmax_}, {ymin_, ymax_}}, y_, ___] :=
With[{pc = PieChart[ConstantArray[1, {y[[-1]]}], ChartStyle->style],
cntr = Mean@Transpose@c},
First[Replace[pc, DiskBox[x_, r_, z_] :> DiskBox[cntr, Scaled[sc], z], {0, Infinity}]]];

BubbleChart[List /@ (Append @@@ Tally[t]),
Prolog -> {Thick, Blue, Line[t]},
ChartElementFunction -> ceF[.05, 64],
PlotRange -> {{0, 6}, {0, 6}}] // Deploy


BubbleChart[List /@ (Append @@@ Tally[tb]),
Prolog -> {Thick, Opacity[.5], Blue, Line[tb]},
ChartElementFunction -> ceF[.04, "Rainbow"]] // Deploy


data = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}};
jitter = 0.5;
ListPlot[data + RandomReal[{-jitter/2, jitter/2}, Dimensions[data]]]


Sort the points, just in case, Split into lists of identical elements and then create a Graphics containing a list of Disk at the appropriate position with size proportional to the number of identical elements.

points = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}};
splitpoints = Split[Sort[points]];
Graphics[Map[Disk[First[#], Length[#]/10] &, splitpoints]]

• This works great, except when you have a LOT of points with the same value, in this case the dots are so big that they hide smaller dots and fill almost the whole figure. Sep 21, 2014 at 17:15
• Which was exactly why I wrote "with size proportional to the number of identical elements." You could replace my /10 scale factor with /100 or /10^29 or even Log[Log[Log[Log[Length[#]]]]] if you have a very large range of different numbers of repetitions. Graphics seems to be all about spending at least several times as much time as it took you to get the calculations correct now fiddling over and over and over trying to get it to look almost like what you think it has to look like to be acceptable.
– Bill
Sep 21, 2014 at 17:54

One idea would be to take the PlotMarker equal to the number of repetitions.

Let's take your example data first:

t = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}};


The first step would be to count the repetitions

ft = Tally[t]

(* {{{1, 2}, 1}, {{3, 4}, 3}, {{4, 5}, 1}} *)

ftlg = Length[ft];
Table[p[i] = ListPlot[{ft[[i]][[1]]}, PlotMarkers -> {ft[[i]][[2]]}, PlotRange -> {{0, 10}, {0, 10}}], {i, 1, ftlg}];

Show[Table[p[i], {i, 1, ftlg}]]


The code is independent of the sample data. So you can try it with more complex data. Of course you could also use other rules to define the PlotMarker.

Regards, Wolfgang

• (at) eldo. Sure, thanks, and sorry for my laziness ... Sep 21, 2014 at 17:33

I would probably use Histogram3D

data = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}};

Histogram3D @ data


You can use colors to distinguish them. Automatically:

lst = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}}
tlst = Counts[lst]
bycounts = Map[DeleteDuplicates, GroupBy[lst, tlst[#] &]]
ListPlot[Values[bycounts]]


Or you can set your own markers with the ListPlot options. For example, you could label each point with its count as follows:

ListPlot[Values[bycounts],
PlotMarkers -> ToString /@ Keys[bycounts]]


• This colors the points but I still can't distinguish them as they are stacked Sep 21, 2014 at 17:13
• The colors are the distinction between them: they are not "stacked", rather the colors indicate how many there are. But see the new edit for labeling with the counts.
– Alan
Sep 21, 2014 at 17:21
• Oh I see I just need a legend for the colors. Sep 21, 2014 at 17:29

TDIL from integr8or'a comment in this Q/A about the new-in-version-12.2 function PointValuePlot which, among other things, provides a more convenient way to visualize data sets with repeated values:

t = {{1, 2}, {3, 4}, {3, 4}, {3, 4}, {4, 5}, {3, 4}, {1, 2}, {6, 7}};

PointValuePlot[Counts[t], PieChart[Table[1, #]]&]


Alternatively,

PointValuePlot[GroupBy[t,Identity, Map[1&]], All -> PieChart]


A cleaner version PointValuePlot[GroupBy[t, Identity, Map[1.&]] should give the same picture, but I could not get an output on Wolfram Cloud.

Use All -> (BarChart[#, Axes -> False]&) to get: