Working with RStudio 0.98.1103, I am creating two versions of exactly the same graph: One with colors and one without. Since both graphs are exactly the same (apart from the coloring) I want to avoid typing nearly the same commands again. Hence, I create the colored plot, save it, manipulate it to make it black-grey-white and save the reduced version:
library(ggplot2)
bp <- ggplot(data=PlantGrowth, aes(x=group, y=weight)) +
geom_line(aes(color=group)) + theme(legend.position="none")
bp_bw <- bp + theme_bw() +
geom_line() + theme(legend.position="none")
ggsave("bp_bw.png", bp_bw)
Although bp looks quite normal, bp_bw doesn't. There is still a blury color shining behind the black bars (red - green - blue):
Closeup:
How can I get rid of this colors, i.e. remove all color completely from bp? Only restriction: I have to create the colored graphs first (although of course a different order would work).
I think a better solution is to create a base and only add the coloring part when needed:
bp <- ggplot(data=PlantGrowth, aes(x=group, y=weight)) +
theme_bw() + theme(legend.position="none")
bp_col <- bp + geom_line(aes(color=group))
bp_bw <- bp + geom_line()
This (more-or-less) makes sense. Your bp_bw code doesn't get rid of the old colored lines, it just adds black lines on top. Anti-aliasing as the image is displayed/saved lets some of the color through on the edges.
My recommendation is to modify the color scale rather than overplot black on top:
bp_bw2 = bp + scale_color_manual(values = rep("black", 20)) + theme_bw()
This will change the colors to all black rather than plotting black on top of colors. The rep("black", 20) is kind of a hack. Apparently values aren't recycled by scale_color_manual, but extra values aren't used so you need to give it a vector at least as long as the number of colors.
This also has the advantage of not needing to repeat the geom call, and if you had previously defined a color scale this will overwrite it. If you want to be more general you could also add a scale_fill_manual(), and you probably want to specify guide = FALSE so that you don't get a very unhelpful legend.
You also might want to check out scale_colour_grey, just because it's B&W doesn't mean all the colors have to be the same.
Related
I am having issue while drawing a graph with ribbons. I came across a sample script in a thread here. That has the same problem.
Below is the script from the thread (slightly modified)
x=1:10
y1=1:10
y2=2:11
y3=10:1
y4=9:0
dt=data.frame(x,y1,y2,y3,y4)
library(ggplot2)
g<-ggplot(dt)+
geom_ribbon(aes(x=x,ymin=y1,ymax=y2,fill='red'),
alpha=0.4)
g<-g + geom_ribbon(aes(x=x,ymin=y3,ymax=y4,fill='blue'),
alpha=0.5)
g<-g + scale_fill_manual(name='legendname',
values=c('red','blue'),
labels=c('one','two'))
The script draws two ribbons called "one" and "two". Ribbon "one" (going up) is supposed to be red and "two" (going down) is supposed to be blue. But the colours are reversed.
If the script is executed step by step you will see that the ribbon one gets drawn as red first and when ribbon two gets drawn it changes colour.
I am totally new to R. So explain to me what is happening here?
According to the ggplot2 documentation (p.10), when you set the argument fill in the aesthetic, you're basically creating a color scale (could be either continuous or discrete, depending on the argument). I'm not sure about the internal implementation of the aes function, but I'm suspecting that since you're passing it a color string, instead of a vector of possible values, the fill argument is simply ignored.
In fact, if you view g before you apply the scale_fill_manual function, you'll see that ggplot2 assigns its default colors to the ribbons, instead of the colors that you selected:
And the reason why the colors are reversed at the end is because when you apply the scale_fill_manual, the color red goes to the layer on top, and the color blue goes to the layer below it.
To get the colors right, what you can do is assign the fill argument to geom_ribbon instead of aes, as follows:
g <- ggplot(dt)
g <- g + geom_ribbon(aes(x=x, ymin=y1, ymax=y2), fill = 'red', alpha=0.4)
g <- g + geom_ribbon(aes(x=x, ymin=y3, ymax=y4), fill = 'blue', alpha=0.5)
Also, you don't need the color scale at the end for this particular example.
I've created a map by overlaying polygons using spplot and with the alpha value of the fill set to 10/255 so that areas with more polygons overlapping have a more saturated color. The polygons are set to two different colors (blue and red) based on a binary variable in the attribute table. Thus, while the color saturation depends on the number of polygons overlapping, the color depends on the ratio of the blue and red classes of polygons.
There is, of course, no easy built-in legend for this so I need to create one from scratch. There is a nice solution to this in base graphics found here. I also came up with a not-so-good hack to do this in ggplot based on this post from kohske. A similar question was posted here and I did my best to give some solutions, but couldn't really come up with a solid answer. Now I need to do the same for myself, but I specifically would like to use R and also use grid graphics.
This is the ggplot hack I came up with
Variable_A <- 100 # max of variable
Variable_B <- 100
x <- melt(outer(1:Variable_A, 1:Variable_B)) # set up the data frame to plot from
p <- ggplot(x) + theme_classic() + scale_alpha(range=c(0,0.5), guide="none") +
geom_tile(aes(x=Var1, y=Var2, fill="Variable_A", col.regions="red", alpha=Var1)) +
geom_tile(aes(x=Var1, y=Var2, fill="Variable_B", col.regions="blue", alpha=Var2)) +
scale_x_continuous(limits = c(0, Variable_A), expand = c(0, 0)) +
scale_y_continuous(limits = c(0, Variable_B), expand = c(0, 0)) +
xlab("Variable_A") + ylab("Variable_B") +
guides(fill=FALSE)
p
Which gives this:
This doesn't work for my purposes for two reasons. 1) Because the alpha value varies, the second color plotted (blue in this case) overwhelms the first one as the alpha values get higher. The correct legend should have blue and red mixed evenly along the 1:1 diagonal. In addition, the colors don't really properly correspond to the map colors. 2) I don't know how to overlay a ggplot object on the lattice map created with spplot. I tried to create a grob using ggplotGrob(p), but still couldn't figure out how to add the grob to the spplot map.
The ideal solution would be to create a similar figure using lattice graphics. I think that using tiles is probably the right solution, but what would be best is to have the alpha values stay constant and vary the number of tiles plotted going from left to right (for red) and bottom to top (for blue). Thus, the colors and saturation should properly match the map (I think...).
Any help is much appreciated!
How about mapping the angle to color, and alpha to the sum of the two variables -- does this do what you want?
d <- expand.grid(x=1:100, y=1:100)
ggplot(d, aes(x, y, fill=atan(y/x), alpha=x+y)) +
geom_tile() +
scale_fill_gradient(high="red", low="blue")+
theme(legend.position="none", panel.background=element_blank())
I am using ggplot2 to create a 2D facet plot. I wish to drop the y-axis strip (because it is self-explanatory) but remove the x-axis strip (because it is not).
I found several examples about how to remove both strips, e.g. this. However, in every case, it was showing you how to get rid of all the labels. There is an example of how to remove the labels from one panel and not the other, but this seems more complicated than I imagine (hope) it actually is. (Also, when I copied and pasted the code, R did not recognize the "unit" command that appeared in the code fragment, though I see that this is addressed elsewhere.)
So, let's say I have the facet grid below, and I want to hide the grey strip for cut, but not color.
require(ggplot2)
pdf(file = sprintf("minimal.pdf"))
p <- ggplot(diamonds, aes(carat, price))
p <- p + geom_point()
p <- p + facet_grid(cut ~ color, scales="fixed")
print(p)
dev.off()
Adding the following line turns both strips white, and removes the characters from the y-strip (cut).
p <- p + theme(strip.text.y = element_blank(), strip.background = element_blank())
That's an improvement, but what I really want to do is keep the x-strip as it was, with the original grey background, but remove the y-strip. Manually adjusting the margins every time I resize the figure, as is done in one of the references, does not seem like a nice way to do it. I am wondering if there is a better way.
You can subset the gtable to remove the column you don't want
g <- ggplotGrob(p)
strips <- subset(g$layout, grepl("strip-right", g$layout$name))
library(grid)
grid.newpage()
grid.draw(g[,-unique(strips$r)])
From what I can find on stackoverflow, (such as this answer to using two scale colour gradients on one ggplot) this may not (yet) be possible with ggplot2.
I want to create a bubbleplot with two size aesthetics, one always larger than the other. The idea is to show the proportion as well as the absolute values. Now I could colour the points by the proportion but I prefer multi-bubbles. In Excel this is relatively simple. (http://i.stack.imgur.com/v5LsF.png) Is there a way to replicate this in ggplot2 (or base)?
Here's an option. Mapping size in two geom_point layers should work. It's a bit of a pain getting the sizes right for bubblecharts in ggplot though.
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(size = disp), shape = 1) +
geom_point(aes(size = hp/(2*disp))) + scale_size_continuous(range = c(15,30))
To get it looking most like your exapmle, add theme_bw():
P <- p + theme_bw()
The scale_size_continuous() is where you have to just fiddle around till you're happy - at least in my experience. If someone has a better idea there I'd love to hear it.
I have a set of data that is heavily right skewed. This creates a problem when doing a stat_bin2d plot. The result is most of the graph is dark blue with only a few points are a different color. I'd like to have the graph use the entire color range a bit more.
An example of the problem is from the ggplot documentation direction.
ggplot(diamonds, aes(carat, price)) + stat_bin2d()
The resulting graph has only a few positions that are something other than dark blue.
How can I adjust the mapping of the color range to show more detail? I know I can set the limits, but this doesn't exactly fit the bill as it makes anything outside the limits be gray.
ggplot(diamonds, aes(carat, price)) + stat_bin2d() + scale_fill_gradient(limits=c(1, 100))
Something like this with they gray appropriately colored too.
The quick answer is
ggplot(diamonds, aes(carat, price)) + stat_bin2d() +
scale_fill_gradient(trans="log10")
EDIT:
A longer answer is that you probably want some kind of transformation of the color or fill scale. For built-in transformations refer to the "See Also" section of
library(scales)
?trans
If none of the built-in transformation is suitable then you can construct your own. See the answers to this SO question about transforming color scales for an example showing how to do this.