Legend for discrete variable with many levels

33 views
Skip to first unread message

bulva

unread,
Apr 4, 2011, 5:55:01 AM4/4/11
to ggplot2
Dear,

I have a plot with clusters of patients (factor with 7 levels, mapped
to color) and their location (factor with 171 levels, mapped to size).
Right now I'm supressing the size legend, as it doesn't fit on the
same viewport as the plot itself. Can I somehow include it, without
obscuring the plot (like on a different viewport fro example) ? My
code so far:


p <- ggplot(mdsdata2d)
p <- p + geom_point(aes(x = coord1, y = coord2, colour = patient, size
= location), shape = 1)

my_scale_size <- scale_size_manual(values = seq(1, 6, length.out =
171))
my_scale_size$legend <- FALSE #supressing size legend

p <- p + my_scale_size
p <- p + geom_vline(aes(x = 0), linetype = 2) + geom_hline(aes(x = 0),
linetype = 2)
p <- p + xlab("Coordinate 1") + ylab("Coordinate 2")
print(p)

Ista Zahn

unread,
Apr 4, 2011, 7:52:54 AM4/4/11
to bulva, ggplot2
Hi,
I think you need to consider what information you want to convey. With
171 sizes, viewers are not going to be able to distinguish the 10th
size from the 11th, or probably even the 10th form the 20th. If they
are ordered you can simply treat location as a continuous variable. If
not, probably mapping any aesthetic to this variable will not produce
very good results. You could instead use facet_wrap to show small
multiples across the 171 levels.

Best,
Ista

> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> Please provide a reproducible example: http://gist.github.com/270442
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>

--
Ista Zahn
Graduate student
University of Rochester
Department of Clinical and Social Psychology
http://yourpsyche.org

Brandon Hurr

unread,
Apr 4, 2011, 7:55:21 AM4/4/11
to Ista Zahn, bulva, ggplot2
How about binning ranges and plotting them instead? 

if (x=1:10) 
x<-1
if (x=11:25)
x<-2
etc...

B

bulva

unread,
Apr 4, 2011, 8:40:31 AM4/4/11
to ggplot2
Hi,
Thanks for Your replies. Points taken, though the location variable
really means coded discrete locations (as if nothing in common, no
particular order etc), so I believe cannot be treated as continuous or
even semi-continuous. The only reason I even consider mapping them to
sizes is outlier detection - every patient type has the same set of
locations recorded, would be insightful to inspect whether the same
locations are outlying in patient clusters.

I was thinking about creating 1 by 2 view-port (1 row, two columns)
and plotting bubble plot on the left with legend for color mapping
only, then only the sizes legend on the second view-port - how can I
extract the legend from the plot though?

On Apr 4, 1:55 pm, Brandon Hurr <brandon.h...@gmail.com> wrote:
> How about binning ranges and plotting them instead?
>
> if (x=1:10)
> x<-1
> if (x=11:25)
> x<-2
> etc...
>
> B
>
> On Mon, Apr 4, 2011 at 12:52, Ista Zahn <iz...@psych.rochester.edu> wrote:
> > Hi,
> > I think you need to consider what information you want to convey. With
> > 171 sizes, viewers are not going to be able to distinguish the 10th
> > size from the 11th, or probably even the 10th form the 20th. If they
> > are ordered you can simply treat location as a continuous variable. If
> > not, probably mapping any aesthetic to this variable will not produce
> > very good results. You could instead use facet_wrap to show small
> > multiples across the 171 levels.
>
> > Best,
> > Ista
>

bulva

unread,
Apr 4, 2011, 8:40:42 AM4/4/11
to ggplot2
Hi,
Thanks for Your replies. Points taken, though the location variable
really means coded discrete locations (as if nothing in common, no
particular order etc), so I believe cannot be treated as continuous or
even semi-continuous. The only reason I even consider mapping them to
sizes is outlier detection - every patient type has the same set of
locations recorded, would be insightful to inspect whether the same
locations are outlying in patient clusters.

I was thinking about creating 1 by 2 view-port (1 row, two columns)
and plotting bubble plot on the left with legend for color mapping
only, then only the sizes legend on the second view-port - how can I
extract the legend from the plot though?

On Apr 4, 1:55 pm, Brandon Hurr <brandon.h...@gmail.com> wrote:
> How about binning ranges and plotting them instead?
>
> if (x=1:10)
> x<-1
> if (x=11:25)
> x<-2
> etc...
>
> B
>
> On Mon, Apr 4, 2011 at 12:52, Ista Zahn <iz...@psych.rochester.edu> wrote:
> > Hi,
> > I think you need to consider what information you want to convey. With
> > 171 sizes, viewers are not going to be able to distinguish the 10th
> > size from the 11th, or probably even the 10th form the 20th. If they
> > are ordered you can simply treat location as a continuous variable. If
> > not, probably mapping any aesthetic to this variable will not produce
> > very good results. You could instead use facet_wrap to show small
> > multiples across the 171 levels.
>
> > Best,
> > Ista
>

Brandon Hurr

unread,
Apr 4, 2011, 9:36:09 AM4/4/11
to bulva, ggplot2
If there is no order and there is nothing in common, how can you put any scale to it whatsoever? 

If you could provide a self-contained example of what you currently have and a drawing of what you want we might be able to get further, but I'm really confused after your last email. 

B

bulva

unread,
Apr 4, 2011, 9:47:46 AM4/4/11
to ggplot2
Please take a look at the plot produced with my previous code, should
become clearer at what am I aiming to (a readable label for size
location). I won't put any data here as it's simply too big (8 files,
2 mb each):

http://dl.dropbox.com/u/5169517/locations_mapped_to_size.eps

I think I know what I will do though. I will simply plot text labels
with locations names instead of points, should be readable and self-
contained

On Apr 4, 3:36 pm, Brandon Hurr <brandon.h...@gmail.com> wrote:
> If there is no order and there is nothing in common, how can you put any
> scale to it whatsoever?
>
> If you could provide a self-contained example of what you currently have and
> a drawing of what you want we might be able to get further, but I'm really
> confused after your last email.
>
> B
>

Brandon Hurr

unread,
Apr 4, 2011, 10:36:38 AM4/4/11
to bulva, ggplot2
I think I understand better, but I'm still not sure how you're really going to compare things. 

If I understand correctly, each patient has a value for a series of 171 locations, and you want to be able to compare the patient data at each location relative to the distribution of the points.  Because you want to look at the distribution of the points and compare locations simultaneously you cannot simply facet the data in chunks.  

I suppose you could plot all the points by color with a very small different type of point, then layer on top of that a subset of the locations. 

Something like...
ggplot(aes(x = coord1, y = coord2, colour=patient))+
geom_point(data = mdsdata2d, size=0.5, shape = 3)+
geom_point(data = droplevels(subset(mdsdata2d, location = 1:10)), aes(size=location))+ 
geom_vline(aes(x = 0), linetype = 2) + 
geom_hline(aes(x = 0), linetype = 2) +
xlab("Coordinate 1") +
ylab("Coordinate 2")

#untested since I don't have a dataset to play with
#I'm really not sure if that subset call with work, 
# I've never tried a range before. 

The only other thing I could think of is mean-centering your patient x and y coordinates and comparing the coordinates of your locations... cum grano salis, IANAS. 

bulva

unread,
Apr 5, 2011, 4:17:15 AM4/5/11
to ggplot2
Many thanks for Your help, I think I will settle for geom_text with
plotted location names as labels. I have tried Your code, the problem
is exacly the same as I had from beginning, namely when using size
mapped to location variable without supressing the legend it obscures
the whole plot (all you can actually see is one big dot). If you use
scale manual then still the label doesn't fit the plot, too many
levels, you're gonna see just the middle values. Subsetting works like
charm though.

Anyway I'm satisfied with the way it looks now, thank you all once
again for helping.

On Apr 4, 4:36 pm, Brandon Hurr <brandon.h...@gmail.com> wrote:
> I think I understand better, but I'm still not sure how you're really going
> to compare things.
>
> If I understand correctly, each patient has a value for a series of 171
> locations, and you want to be able to compare the patient data at each
> location relative to the distribution of the points.  Because you want to
> look at the distribution of the points and compare locations simultaneously
> you cannot simply facet the data in chunks.
>
> I suppose you could plot all the points by color with a very small different
> type of point, then layer on top of that a subset of the locations.
>
> Something like...
> ggplot(aes(x = coord1, y = coord2, colour=patient))+
> geom_point(data = mdsdata2d, size=0.5, shape = 3)+
> geom_point(data = droplevels(subset(mdsdata2d, location = 1:10)),
> aes(size=location))+
> geom_vline(aes(x = 0), linetype = 2) +
> geom_hline(aes(x = 0), linetype = 2) +
> xlab("Coordinate 1") +
> ylab("Coordinate 2")
>
> #untested since I don't have a dataset to play with
> #I'm really not sure if that subset call with work,
> # I've never tried a range before.
>
> The only other thing I could think of is mean-centering your patient x and y
> coordinates and comparing the coordinates of your locations... *cum grano
> salis*, IANAS.
>
> B
Reply all
Reply to author
Forward
0 new messages