7
$\begingroup$

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?

$\endgroup$
8
$\begingroup$

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])]

enter image description here

$\endgroup$
  • 2
    $\begingroup$ If you make it PointSize[Sqrt[#2]/50] then the area of the dots will be proportional to the tally, which seems more appropriate. $\endgroup$ – Rahul Sep 22 '14 at 4:30
  • $\begingroup$ @RahulNarain Ok. Thanks. $\endgroup$ – Algohi Sep 22 '14 at 12:59
6
$\begingroup$

Jittering is a popular way to handle overplotting of discrete data.

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

enter image description here

$\endgroup$
6
$\begingroup$

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]

enter image description here

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}]

enter image description here

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}}]

enter image description here

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

enter image description here

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

enter image description here

$\endgroup$
2
$\begingroup$

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]]
$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – Sulli Sep 21 '14 at 17:15
  • $\begingroup$ 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. $\endgroup$ – Bill Sep 21 '14 at 17:54
2
$\begingroup$

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}]]

enter image description here

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

$\endgroup$
  • $\begingroup$ (at) eldo. Sure, thanks, and sorry for my laziness ... $\endgroup$ – Dr. Wolfgang Hintze Sep 21 '14 at 17:33
1
$\begingroup$

I would probably use Histogram3D

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

Histogram3D @ data

enter image description here

$\endgroup$
1
$\begingroup$

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]]

using counts as markers

$\endgroup$
  • $\begingroup$ This colors the points but I still can't distinguish them as they are stacked $\endgroup$ – Sulli Sep 21 '14 at 17:13
  • $\begingroup$ 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. $\endgroup$ – Alan Sep 21 '14 at 17:21
  • $\begingroup$ Oh I see I just need a legend for the colors. $\endgroup$ – Sulli Sep 21 '14 at 17:29

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.