In my work, I frequently display scatterplots using text labels. That's meant a plot() command, followed by text(). I used cex to adjust to font size to what I wanted it very quickly.
I created a text scatterplot very quickly using qplot. But I can't adjust the size fast. Here's a silly code example:
data(state)
qplot(Income, Population,
data=as.data.frame(state.x77),
geom=c("smooth", "text"), method="lm",
label=state.abb)
Whereas in the old days I'd do:
plot(xlim=range(Income), ylim=range(Population),
data=state.x77, type="n")
text(Income, Population, state.abb,
data=state.x77, cex=.5)
If I wanted the text size halved from what I saw at the defaults (oh, and I'd have to do a linear regression manually and add abline() to get the regression line -- nice to do it all in one via ggplot2).
I know I can add a size adjustment with size, but it's not a relative size adjustment like I'm used to. Hadley tweeted me to say that size is measured in mm, which isn't fully intuitive to me. Since I often adjust the size of the plot, either in R or in LaTeX, an absolute scale isn't as useful to me.
I must be missing something really simple. What is it?
I think you are tyring to adjust the size of the text itself, not the x-axis, right?
Here's an approach using the ggplot() command.
ggplot(data = as.data.frame(state.x77), aes(x = Income, y = Population)) +
geom_smooth(method = "lm", se = FALSE) +
geom_text(aes(label = state.abb), size = 2.5)
qp <- qplot(Income, Population,data=as.data.frame(state.x77),
geom=c("smooth","text"),
method="lm",
label=state.abb)
qp + opts(axis.text.x = theme_text(size = 5))
I think Chase is probably right about wanting points as "labels":
qp <- qplot(Income, Population,data=as.data.frame(state.x77),
geom="smooth",method="lm",label=state.abb)
qp + geom_text(aes(label = state.abb), size = 2.5)
If "text" is given in the geom argument to qplot the default size is used and then gets overwritten (or underwritten as it were in this case). Give Chase the check. (Edit: should make size 2.5)
Edit2: Took digging but I found the way to get ggplot2 to cough up some of its defaults:
https://github.com/hadley/ggplot2/blob/master/R/geom-text.r
GeomText$new()$geom$default_aes
proto method (instantiated with ): function (.)
aes(colour = "black", size = 5, angle = 0, hjust = 0.5, vjust = 0.5,
alpha = 1)
There's got to be a better way....
qp <- qplot(Income, Population,data=as.data.frame(state.x77),
geom="smooth",method="lm",label=state.abb)
qp + geom_text(aes(label = state.abb, cex = 1.2))
Add cex inside aes will get what you want, as quoted from:
aes creates a list of unevaluated expressions. This function also performs partial name matching, converts color to colour, and old style R names to ggplot names (eg. pch to shape, cex to size)
http://docs.ggplot2.org/current/aes.html
Related
I am opening this question for three reasons : First, to re-open the dual-axis discussion with ggplot. Second, to ask if there is a non-torturing generic approach to do that. And finally to ask for your help with respect to a work-around.
I realize that there are multiple discussions and questions on how to add a secondary axis to a ggplot. Those usually end up in one of two conclusions:
It's bad, don't do it: Hadley Wickham answered the same question here, concluding that it is not possible. He had a very good argument that "using separate y scales (not y-scales that are transformations of each other) are fundamentally flawed".
If you insist, over-complicate your life and use grids : for example here and here
However, here are some situations that I often face, in which the visualization would greatly benefit from dual-axis. I abstracted the concepts below.
The plot is wide, hence duplicating the y-axis on the right side would help (or x-axis on the top) would ease interpretation. (We've all stumbled across one of those plots where we need to use a ruler on the screen, because the axis is too far)
I need to add a new axis that is a transformation to the original axes (eg: percentages, quantiles, .. ). (I am currently facing a problem with that. Reproducible example below)
And finally, adding Grouping/Meta information: I stumble across that when using categorical data with multiple-level, (e.g.: Categories = {1,2,x,y,z}, which are "meta-divided" into letters and numerics.) Even though color-coding the meta-levels and adding a legend or even facetting solve the issue, things get a little bit simpler with a secondary axis, where the user won't need to match the color of the bars to that of the legend.
General question: Given the new extensibility features ggplot 2.0.0, is there a more-robust no-torture way to have dual-axis without using grids?
And one final comment: I absolutely agree that the wrong use of dual-axis can be dangerously misleading... But, isn't that the case for information visualization and data science in general?
Work-around question:
Currently, I need to have a percentage-axis (2nd case). I used annotate and geom_hline as a workaround. However, I can't move the text outside the main plot. hjust also didn't seem to work with me.
Reproducible example:
library(ggplot2)
# Random values generation - with some manipulation :
maxVal = 500
value = sample(1:maxVal, size = 100, replace = T)
value[value < 400] = value[value < 400] * 0.2
value[value > 400] = value[value > 400] * 0.9
# Data Frame prepartion :
labels = paste0(sample(letters[1:3], replace = T, size = length(value)), as.character(1:length(value)))
df = data.frame(sample = factor(labels, levels = labels), value = sort(value, decreasing = T))
# Plotting : Adding Percentages/Quantiles as lines
ggplot(data = df, aes(x = sample, y = value)) +
geom_bar(stat = "identity", fill = "grey90", aes(y = maxVal )) +
geom_bar(stat = "identity", fill = "#00bbd4") +
geom_hline(yintercept = c(0, maxVal)) + # Min and max values
geom_hline(yintercept = c(maxVal*0.25, maxVal*0.5, maxVal*0.75), alpha = 0.2) + # Marking the 25%, 50% and 75% values
annotate(geom = "text", x = rep(100,3), y = c(maxVal*0.25, maxVal*0.5, maxVal*0.75),
label = c("25%", "50%", "75%"), vjust = 0, hjust = 0.2) +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
theme(panel.background = element_blank()) +
theme(plot.background = element_blank()) +
theme(plot.margin = unit(rep(2,4), units = "lines"))
In response to #1
We've all stumbled across one of those plots where we need to use a ruler on the screen, because the axis is too far
cowplot.
# Assign your original plot to some variable, `gpv` <- ggplot( ... )
ggdraw(switch_axis_position(gpv, axis="y", keep="y"))
I need to adjust the legend for the following barplot in a proper position somewhere outside the plot
COLORS=rainbow(18)
barplot(sort(task3_result$respondents_share,decreasing = TRUE), main="Share of respondents that mentioned brand among top 3 choices ", names.arg=task3_result$brand, col = COLORS)
legend("right", tolower(as.character(task3_result$brand)), yjust=1,col = COLORS, lty=c(1,1) )
Thanks guys, i couldn't solve the problem but i reached my goal using ggplot,
windows(width = 500, height= 700)
ggplot(data = task3_result, aes(x = factor(brand), y = respondents_share, fill = brand)) +
geom_bar(colour = 'black', stat = 'identity') + scale_fill_discrete(name = 'brands') + coord_flip()+
ggtitle('Share of respondents that mentioned brand among top 3 choices') +xlab("Brands") + ylab("Share of respondents")
As DatamineR pointed out, your code is not reproducible as-is (we don't have task3_result), but you can probably accomplish what you're talking about by playing with the x and y arguments to legend() - you can just set the x coordinate to something beyond the edges of the bars, for example. See the documentation: https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/legend.html. Also note there the cex argument, because that legend might be bulkier than you want.
Note that you will have to specify a larger plot window in order to leave space for the legend; the relevant help file for that is plot.window: https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/plot.window.html
Though you won't want to call plot.window directly - better to pass the relevant arguments to it through the barplot() function. If that doesn't make sense, I recommend you read up on R's base plotting package more generally.
Attempting to repurpose code for political survey I found on reddit for much smaller sample size.
I am creating a scatterplot using geom_jitter. Here is my code:
ggplot(sae, aes(Alignment, Abortion))+
geom_jitter(aes(color = "green"), size = 4, alpha = 0.6)+
labs("Alignment", "Stance on Abortion")
Here is the graph it gives:
How do I make the grouping around the "Pro-choice" or the "Pro-life" lines tighter? I believe this current graph would confuse many people as to which observations are pro-choice or pro-life.
Extra credit for helping with the color problem.
You have a bigger problem. The x-axis is ordered alphabetically, which is very confusing and probably not what you intended. Also, you probably need to specify both the width (jitter in x-direction) and height (jitter in y direction).
You can fix the ordering using, e.g.,
sae$Alignment <- factor(sae$Alignment, levels=unique(sae$Alignment))
as demonstrated below.
# make up some data - you have this already
set.seed(1) # for reproducible example
sae <- data.frame(Alignment=rep(c("Left","Left Leaning","Center","Right Leaning","Right"),each=5),
Abortion =sample(c("Pro Choice","Pro Life","Other"),25, replace=TRUE))
# you start here...
library(ggplot2)
sae$Alignment <- factor(sae$Alignment, levels=unique(sae$Alignment))
ggplot(sae, aes(Alignment, Abortion))+
geom_point(color = "green", size = 4, alpha = 0.6, position=position_jitter(width=0.1, height=0.1))+
labs("Alignment", "Stance on Abortion")
Also, IMO, you could do better viz. colors:
sae$Orientation <- with(sae,ifelse(grepl("Left",Alignment),"Progressive",
ifelse(grepl("Right",Alignment),"Conservative","Neutral")))
ggplot(sae, aes(x=Alignment, y=Abortion, color=Orientation))+
geom_point(size = 4, alpha = 0.6, position=position_jitter(width=0.1, height=0.1))+
labs("Alignment", "Stance on Abortion")
You can set the width parameter in position = position_jitter() to control how tight the points are.
ggplot(sae, aes(Alignment, Abortion)) +
geom_jitter(color = "green", size = 4, alpha = 0.6, position = position_jitter(width = .2)) +
labs("Alignment", "Stance on Abortion")
If you're using the newest development version of ggplot2 (1.0.1.9003), you can just do geom_jitter(width = .2, ...) instead.
If it's still too wide, decrease width to a smaller value (and vice versa). Also note that to change the color of the points, I removed the aes() around color = "green".
Having hit this problem just recently, none of the answers above give an optimal solution.
I found an elegant answer using geom_beeswarm in library(geom_beeswarm) and thought I'd post it here.
Reproducing with geom_jitter using mpg is fairly messy:
data(mpg)
ggplot(mpg, aes(x=cyl, y=hwy, group=factor(cyl))) +
geom_boxplot() +
geom_jitter(position = position_jitter(height = .2, width = .2))
Whereas geom_beeswarm makes the jitter points centralised and much clearer:
library(geom_beeswarm)
data(mpg)
ggplot(mpg, aes(x=cyl, y=hwy, group=factor(cyl))) +
geom_boxplot() +
geom_beeswarm()
I have a continous variable that I would like to map to the color of my points.
However the distribution of the variable is shifted tot the right.
So I thought I could use the quantiles to set the breaks but this doesn't seem to be working.
I think I don't understand the subtleties between all of the different variants of scale_colour_gradient.
ggplot(df, aes(x = LibPl, y = IntStd, color = totSmpInt)) +
geom_point(position = "jitter", alpha = 0.5) +
scale_colour_gradientn(colours = brewer.pal(n = 4, "RdYlBu"),
breaks = c(qn[1], qn[2], qn[3], qn[4], qn[5]))
As you can see from the color legend in the plot it doesn't really seem like the quantiles were used as break points.
I have read a few other similar posts, and tried variants, but none are working
Any help is appreciated.
Thanks,
Can I adjust the point size, alpha, font, and axis ticks in a plotmatrix?
Here is an example:
library(ggplot2)
plotmatrix(iris)
How can I:
make the points twice as big
set alpha = 0.5
have no more than 5 ticks on each axis
set font to 1/2 size?
I have fiddled with the mapping = aes() argument to plotmatrix as well as opts() and adding layers such as + geom_point(alpha = 0.5, size = 14), but none of these seem to do anything. I have hacked a bit of a fix to the size by writing to a large pdf (pdf(file = "foo.pdf", height = 10, width = 10)), but this provides only a limited amount of control.
Pretty much all of the ggplot2 scatterplot matrix options are still fairly new and can be a bit experimental.
But the facilities in GGally do allows you to construct this kind of plot manually, though:
custom_iris <- ggpairs(iris,upper = "blank",lower = "blank",
title = "Custom Example")
p1 <- ggplot(iris,aes(x = Sepal.Length,y = Sepal.Width)) +
geom_point(size = 1,alpha = 0.3)
p2 <- ggplot(iris,aes(x = Sepal.Width,y = Sepal.Length)) +
geom_point()
custom_iris <- putPlot(custom_iris,p1,2,1)
custom_iris <- putPlot(custom_iris,p2,3,2)
custom_iris
I did that simply by directly following the last example in ?ggpairs.