I have a graph of wind speeds against direction which has a huge numeber of points, and so am using alpha=I(1/20) in addition to color=month
Here is a sample of code:
library(RMySQL)
library(ggplot2)
con <- dbConnect(...)
wind <- dbGetQuery(con, "SELECT speed_w/speed_e AS ratio, dir_58 as dir, MONTHNAME(timestamp) AS month, ROUND((speed_w+speed_e)/2) AS speed FROM tablename;");
png("ratio-by-speed.png",height=400,width=1200)
qplot(wind$dir,wind$ratio,ylim=c(0.5,1.5),xlim=c(0,360),color=wind$month,alpha=I(1/30),main="West/East against direction")
dev.off()
This produces a decent graph, however my issue is that the alpha of the legend is 1/30th also, which makes it unreadable. Is there a way I can force the legend to be 1 alpha instead?
Here is an example:
Update With the release of version 0.9.0, one can now override aesthetic values in the legend using override.aes in the guides function. So if you add something like this to your plot:
+ guides(colour = guide_legend(override.aes = list(alpha = 1)))
that should do it.
I've gotten around this by doing a duplicate call to the geom using an empty subset of the data and using the legend from that call. Unfortunately, it doesn't work if the data frame is actually empty (e.g. as you'd get from subset(diamonds,FALSE)) since ggplot2 seems to treat this case the same as it treats NULL in place of a data frame. But we can get the same effect by taking a subset with only one row and setting it to NaN on one of the plot dimensions, which will prevent it from getting plotted.
Based off Chase's example:
# Alpha parameter washes out legend:
gp <- ggplot() + geom_point(data=diamonds, aes(depth, price, colour=clarity), alpha=0.1)
print(gp)
# Full color legend:
dummyData <- diamonds[1, ]
dummyData$price <- NaN
#dummyData <- subset(diamonds, FALSE) # this would be nicer but it doesn't work!
gp <- ggplot() +
geom_point(data=diamonds, aes(depth, price, colour=clarity), alpha=0.1, legend=FALSE) +
geom_point(data=dummyData, aes(depth, price, colour=clarity), alpha=1.0, na.rm=TRUE)
print(gp)
A bit of googling turned up this post which doesn't seem to indicate that ggplot currently supports this option. Others have addressed related problems by using gridExtra and using viewPorts as discussed here.
I'm not that sophisticated, but here's one approach that should give you the desired results. The approach is to plot the geom twice, once without an alpha parameter and outside of the real plotting area. The second geom will include the alpha parameter and suppress the legend. We will then specify the plotting region with xlim and ylim. Given that you are a lot of points, this will roughly double the plotting time, but should give you the effect you are after.
Using the diamonds dataset:
#Alpha parameter washes out legend
ggplot(data = diamonds, aes(depth, price, colour = clarity)) +
geom_point(alpha = 1/10)
#Fully colored legend
ggplot() +
geom_point(data = diamonds, aes(depth, price, colour =clarity), alpha = 1/10, legend = FALSE) +
geom_point(data = diamonds, aes(x = depth - 999999, y = price - 999999, colour = clarity)) +
xlim(40, 80) + ylim(0, 20000)
Related
I have a graph of wind speeds against direction which has a huge numeber of points, and so am using alpha=I(1/20) in addition to color=month
Here is a sample of code:
library(RMySQL)
library(ggplot2)
con <- dbConnect(...)
wind <- dbGetQuery(con, "SELECT speed_w/speed_e AS ratio, dir_58 as dir, MONTHNAME(timestamp) AS month, ROUND((speed_w+speed_e)/2) AS speed FROM tablename;");
png("ratio-by-speed.png",height=400,width=1200)
qplot(wind$dir,wind$ratio,ylim=c(0.5,1.5),xlim=c(0,360),color=wind$month,alpha=I(1/30),main="West/East against direction")
dev.off()
This produces a decent graph, however my issue is that the alpha of the legend is 1/30th also, which makes it unreadable. Is there a way I can force the legend to be 1 alpha instead?
Here is an example:
Update With the release of version 0.9.0, one can now override aesthetic values in the legend using override.aes in the guides function. So if you add something like this to your plot:
+ guides(colour = guide_legend(override.aes = list(alpha = 1)))
that should do it.
I've gotten around this by doing a duplicate call to the geom using an empty subset of the data and using the legend from that call. Unfortunately, it doesn't work if the data frame is actually empty (e.g. as you'd get from subset(diamonds,FALSE)) since ggplot2 seems to treat this case the same as it treats NULL in place of a data frame. But we can get the same effect by taking a subset with only one row and setting it to NaN on one of the plot dimensions, which will prevent it from getting plotted.
Based off Chase's example:
# Alpha parameter washes out legend:
gp <- ggplot() + geom_point(data=diamonds, aes(depth, price, colour=clarity), alpha=0.1)
print(gp)
# Full color legend:
dummyData <- diamonds[1, ]
dummyData$price <- NaN
#dummyData <- subset(diamonds, FALSE) # this would be nicer but it doesn't work!
gp <- ggplot() +
geom_point(data=diamonds, aes(depth, price, colour=clarity), alpha=0.1, legend=FALSE) +
geom_point(data=dummyData, aes(depth, price, colour=clarity), alpha=1.0, na.rm=TRUE)
print(gp)
A bit of googling turned up this post which doesn't seem to indicate that ggplot currently supports this option. Others have addressed related problems by using gridExtra and using viewPorts as discussed here.
I'm not that sophisticated, but here's one approach that should give you the desired results. The approach is to plot the geom twice, once without an alpha parameter and outside of the real plotting area. The second geom will include the alpha parameter and suppress the legend. We will then specify the plotting region with xlim and ylim. Given that you are a lot of points, this will roughly double the plotting time, but should give you the effect you are after.
Using the diamonds dataset:
#Alpha parameter washes out legend
ggplot(data = diamonds, aes(depth, price, colour = clarity)) +
geom_point(alpha = 1/10)
#Fully colored legend
ggplot() +
geom_point(data = diamonds, aes(depth, price, colour =clarity), alpha = 1/10, legend = FALSE) +
geom_point(data = diamonds, aes(x = depth - 999999, y = price - 999999, colour = clarity)) +
xlim(40, 80) + ylim(0, 20000)
Hi I am trying to code for a scatter plot for three variables in R:
Race= [0,1]
YOI= [90,92,94]
ASB_mean = [1.56, 1.59, 1.74]
Antisocial <- read.csv(file = 'Antisocial.csv')
Table_1 <- ddply(Antisocial, "YOI", summarise, ASB_mean = mean(ASB))
Table_1
Race <- unique(Antisocial$Race)
Race
ggplot(data = Table_1, aes(x = YOI, y = ASB_mean, group_by(Race))) +
geom_point(colour = "Black", size = 2) + geom_line(data = Table_1, aes(YOI,
ASB_mean), colour = "orange", size = 1)
Image of plot: https://drive.google.com/file/d/1E-ePt9DZJaEr49m8fguHVS0thlVIodu9/view?usp=sharing
Data file: https://drive.google.com/file/d/1UeVTJ1M_eKQDNtvyUHRB77VDpSF1ASli/view?usp=sharing
Can someone help me understand where I am making mistake? I want to plot mean ASB vs YOI grouped by Race. Thanks.
I am not sure what is your desidered output. Maybe, if I well understood your question I Think that you want somthing like this.
g_Antisocial <- Antisocial %>%
group_by(Race) %>%
summarise(ASB = mean(ASB),
YOI = mean(YOI))
Antisocial %>%
ggplot(aes(x = YOI, y = ASB, color = as_factor(Race), shape = as_factor(Race))) +
geom_point(alpha = .4) +
geom_point(data = g_Antisocial, size = 4) +
theme_bw() +
guides(color = guide_legend("Race"), shape = guide_legend("Race"))
and this is the output:
#Maninder: there are a few things you need to look at.
First of all: The grammar of graphics of ggplot() works with layers. You can add layers with different data (frames) for the different geoms you want to plot.
The reason why your code is not working is that you mix the layer call and or do not really specify (and even mix) what is the scatter and line visualisation you want.
(I) Use ggplot() + geom_point() for a scatter plot
The ultimate first layer is: ggplot(). Think of this as your drawing canvas.
You then speak about adding a scatter plot layer, but you actually do not do it.
For example:
# plotting antisocal data set
ggplot() +
geom_point(data = Antisocial, aes(x = YOI, y = ASB, colour = as.factor(Race)))
will plot your Antiscoial data set using the scatter, i.e. geom_point() layer.
Note that I put Race as a factor to have a categorical colour scheme otherwise you might end up with a continous palette.
(II) line plot
In analogy to above, you would get for the line plot the following:
# plotting Table_1
ggplot() +
geom_line(data = Table_1, aes(x = YOI, y = ASB_mean))
I save showing the plot of the line.
(III) combining different layers
# putting both together
ggplot() +
geom_point(data = Antisocial, aes(x = YOI, y = ASB, colour = as.factor(Race))) +
geom_line(data = Table_1, aes(x = YOI, y = ASB_mean)) +
## this is to set the legend title and have a nice(r) name in your colour legend
labs(colour = "Race")
This yields:
That should explain how ggplot-layering works. Keep an eye on the datasets and geoms that you want to use. Before working with inheritance in aes, I recommend to keep the data= and aes() call in the geom_xxxx. This avoids confustion.
You may want to explore with geom_jitter() instead of geom_point() to get a bit of a better presentation of your dataset. The "few" points plotted are the result of many datapoints in the same position (and overplotted).
Moving away from plotting to your question "I want to plot mean ASB vs YOI grouped by Race."
I know too little about your research to fully comprehend what you mean with that.
I take it that the mean ASB you calculated over the whole population is your reference (aka your Table_1), and you would like to see how the Race groups feature vs this population mean.
One option is to group your race data points and show them as boxplots for each YOI.
This might be what you want. The boxplot gives you the median and quartiles, and you can compare this per group against the calculated ASB mean.
For presentation purposes, I highlighted the line by increasing its size and linetype. You can play around with the colours, etc. to give you the aesthetics you aim for.
Please note, that for the grouped boxplot, you also have to treat your integer variable YOI, I coerced into a categorical factor. Boxplot works with fill for the body (colour sets only the outer line). In this setup, you also need to supply a group value to geom_line() (I just assigned it to 1, but that is arbitrary - in other contexts you can assign another variable here).
ggplot() +
geom_boxplot(data = Antisocial, aes(x = as.factor(YOI), y = ASB, fill = as.factor(Race))) +
geom_line(data = Table_1, aes(x = as.factor(YOI), y = ASB_mean, group = 1)
, size = 2, linetype = "dashed") +
labs(x = "YOI", fill = "Race")
Hope this gets you going!
I have two data frames: one I am using to create the bars in a barchart and a second that I am using to create a shaded "target region" behind the bars using geom_rect.
Here is example data:
test.data <- data.frame(crop=c("A","B","C"), mean=c(6,4,12))
target.data <- data.frame(crop=c("ONE","TWO"), mean=c(31,12), min=c(24,9), max=c(36,14))
I start with the means of test.data for the bars and means of target.data for the line in the target region:
library(ggplot2)
a <- ggplot(test.data, aes(y=mean, x=crop)) + geom_hline(aes(yintercept = mean, color = crop), target.data) + geom_bar(stat="identity")
a
So far so good, but then when I try to add a shaded region to display the min-max range of target.data, there is an issue. The shaded region appears just fine, but somehow, the crops from target.data are getting added to the x-axis. I'm not sure why this is happening.
b <- a + geom_rect(aes(xmin=-Inf, xmax=Inf, ymin=min, ymax=max, fill = crop), data = target.data, alpha = 0.5)
b
How can I add the geom_rect shapes without adding those extra names to the x-axis of the bar-chart?
This is a solution to your question, but I'd like to better understand you problem because we might be able to make a more interpretable plot. All you have to do is add aes(x = NULL) to your geom_rect() call. I took the liberty to change the variable 'crop' in add.data to 'brop' to minimize any confusion.
test.data <- data.frame(crop=c("A","B","C"), mean=c(6,4,12))
add.data <- data.frame(brop=c("ONE","TWO"), mean=c(31,12), min=c(24,9), max=c(36,14))
ggplot(test.data, aes(y=mean, x=crop)) +
geom_hline(data = add.data, aes(yintercept = mean, color = brop)) +
geom_bar(stat="identity") +
geom_rect(data = add.data, aes(xmin=-Inf, xmax=Inf, x = NULL, ymin=min, ymax=max, fill = brop),
alpha = 0.5, show.legend = F)
In ggplot calls all of the aesthetics or aes() are inherited from the intial call:
ggplot(data, aes(x=foo, y=bar)).
That means that regardless of what layers I add on geom_rect(), geom_hline(), etc. ggplot is looking for 'foo' to assign to x and 'bar' to assign to y, unless you specifically tell it otherwise. So like aeosmith pointed out you can clear all inherited aethesitcs for a layer with inherit.aes = FALSE, or you can knock out single variables at a time by reassigning them as NULL.
I'm currently working on a very simple data.frame, containing three columns:
x contains x-coordinates of a set of points,
y contains y-coordinates of the set of points, and
weight contains a value associated to each point;
Now, working in ggplot2 I seem to be able to plot contour levels for these data, but i can't manage to find a way to fill the plot according to the variable weight. Here's the code that I used:
ggplot(df, aes(x,y, fill=weight)) +
geom_density_2d() +
coord_fixed(ratio = 1)
You can see that there's no filling whatsoever, sadly.
I've been trying for three days now, and I'm starting to get depressed.
Specifying fill=weight and/or color = weight in the general ggplot call, resulted in nothing. I've tried to use different geoms (tile, raster, polygon...), still nothing. Tried to specify the aes directly into the geom layer, also didn't work.
Tried to convert the object as a ppp but ggplot can't handle them, and also using base-R plotting didn't work. I have honestly no idea of what's wrong!
I'm attaching the first 10 points' data, which is spaced on an irregular grid:
x = c(-0.13397460,-0.31698730,-0.13397460,0.13397460,-0.28867513,-0.13397460,-0.31698730,-0.13397460,-0.28867513,-0.26794919)
y = c(-0.5000000,-0.6830127,-0.5000000,-0.2320508,-0.6547005,-0.5000000,-0.6830127,-0.5000000,-0.6547005,0.0000000)
weight = c(4.799250e-01,5.500250e-01,4.799250e-01,-2.130287e+12,5.798250e-01,4.799250e-01,5.500250e-01,4.799250e-01,5.798250e-01,6.618956e-01)
any advise? The desired output would be something along these lines:
click
Thank you in advance.
From your description geom_density doesn't sound right.
You could try geom_raster:
ggplot(df, aes(x,y, fill = weight)) +
geom_raster() +
coord_fixed(ratio = 1) +
scale_fill_gradientn(colours = rev(rainbow(7)) # colourmap
Here is a second-best using fill=..level... There is a good explanation on ..level.. here.
# load libraries
library(ggplot2)
library(RColorBrewer)
library(ggthemes)
# build your data.frame
df <- data.frame(x=x, y=y, weight=weight)
# build color Palette
myPalette <- colorRampPalette(rev(brewer.pal(11, "Spectral")), space="Lab")
# Plot
ggplot(df, aes(x,y, fill=..level..) ) +
stat_density_2d( bins=11, geom = "polygon") +
scale_fill_gradientn(colours = myPalette(11)) +
theme_minimal() +
coord_fixed(ratio = 1)
I have trolled ggplot2 documentation, Stack and the ggplot2 Google groups email list - but to no avail.
Please can someone tell me how to merge the legends for alpha (opacity) and size? They are titled "(1-val2)" and "val2", respectively.
Normally mapping alpha and size to val2 would automatically merge the axes. However because I'm using "val2" and "1-val2", this does not happen. I have played around with scale_size_continuous and scale_alpha_continuous, but didn't manage to come right.
Here is a MWE:
require(ggplot2)
dummy <- data.frame(x=c(runif(12,5,10)),
y=c(runif(12,5,10)),
val1=c("a","b","c","a","b","c","a","b","c","a","b","c"),
val2=c(0.4,0.6,0.7,0.2,0.8,0.6,0.7,0.2,0.5,0.8,0.4,0.7))
p <- ggplot() +
geom_point(data=dummy, aes(x=x, y=y,color=val1, size=val2, alpha=(1-val2)))
Use the range argument of scale_alpha_continuous to invert the scale:
ggplot() +
geom_point(data=dummy, aes(x=x, y=y,color=val1, size=val2, alpha=val2)) +
scale_alpha_continuous(range = c(1, 0.1))
The trans argument may also be useful here:
ggplot() +
geom_point(data=dummy, aes(x = x, y = y, color = val1, size = val2, alpha = val2)) +
scale_alpha_continuous(trans = "reverse")
The description of the trans argument in ?scale_alpha_continuous and ?continuous_scale is pretty thin. However, you can find some examples here.