I am trying to build a type of color density plot similar to the one here:
https://stats.stackexchange.com/questions/26676/generating-visually-appealing-density-heat-maps-in-r
But with different types of data that goes into it. My real data has a bunch of rows but for example I have code that is put into a data frame that is X, Y, Score and I want to have a color density plot using these static X, Y buckets. Is that possible?
X=seq(0,10,by=1)
Y=seq(50,60,by=1)
total=expand.grid(X,Y)
nrow(total)
total$score=runif(nrow(total), min=0, max=100)
range(total$score)
head(total)
my_palette <- colorRampPalette(c("blue", "yellow", "red"))(n = 100)
col_breaks = c(seq(0,100,length=100))
col=data.frame(as.character(my_palette),col_breaks)
col$num=row.names(col)
head(col)
col$col_breaks=round(col$col_breaks,0)
names(col)[1]="hex"
total$round=round(total$score)
total$color=as.character(col$hex[match(total$round,col$col_breaks)])
plot(total$Var1,total$Var2,col=total$color,xlim=c(0,10),ylim=c(50,60))
I am not trying to hexbin or anything confine into boxes, figured that out using conditional rect() with colors but wondering with this type of data if there is a way for it to sort of be more of a freeflowing shape of heat similar to this:
Or does it need to be continuous data to do something like that?
If I understand your question correctly, I think you can do this in ggplot.
Basically you can use geom_raster to fill in the tiles with an interpolate option so it won't look "blocky". You can then set the gradient to what you want. So for example, based on the sample data you gave me I have set the low, mid, high colours to be blue, white and red respectively. It would simply be the following code:
library(ggplot2)
ggplot(total, aes(x=Var1, y=Var2)) +
geom_raster(aes(fill=score), interpolate=TRUE) +
scale_fill_gradient2(limits=c(0,100), low="blue", mid="white", high="red", midpoint = 50)
Output:
Related
I am doing kmeans clustering on a png image and have been plotting it using grid::grid.raster(image). But I would like to put a legend which shows the intensity in a bar(from blue to red) marked with values, essentially indicating the intensity on the image. (image is an array where the third dimension equals 3 giving the red, green and blue channels.)
I thought of using grid.legend() but couldn't figure it out. I am hoping the community can help me out. Following is the image I have been using and after I perform kmeans clustering want a legend beside it that displays intensity on a continuous scale on a color bar.
Also I tried with ggplot2 and could plot the image but still couldn't plot the legend. I am providing the ggplot code for plotting the image. I can extract the RGB channels separately using ggplot2 also, so showing that also helps.
colassign <- rgb(Kmeans2#centers[clusters(Kmeans2),])
library(ggplot2)
ggplot(data = imgVEC, aes(x = x, y = y)) +
geom_point(colour = colassign) +
labs(title = paste("k-Means Clustering of", kClusters, "Colours")) +
xlab("x") +
ylab("y")
Did not find a way to use grid.raster() properly but found a way to do it by ggplot2 when plotting the RGB channels separately. Note: this only works for plotting the pannels separately, but this is what I needed. Following shows the code for green channel.
#RGB channels are respectively stored in columns 1,2,3.
#x-axis and y-axis values are stored in columns 4,5.
#original image is a nx5 matrix
ggplot(original_img[,c(3,4,5)], aes(x, y)) +
geom_point(aes(colour = segmented_img[,3])) +
scale_color_gradient2()+
# scale_color_distiller(palette="RdYlBu") can be used instead of scale_color_gradient2() to get color selections of choice using palette as argument.
I was creating histograms with ggplot2 in R whose bins are separated with colors and noticed one thing. When the bins of a histogram are separated by colors with fill option, the density value of the histogram turns funny.
Here is the data.
set.seed(42)
x <- rnorm(10000,0,1)
df <- data.frame(x=x, b=x>1)
This is a histogram without fill.
ggplot(df, aes(x = x)) +
geom_histogram(aes(y=..density..))
This is a histogram with fill.
ggplot(df, aes(x = x, fill=b)) +
geom_histogram(aes(y=..density..))
You can see the latter is pretty crazy. The left side of the bins is sticking out. The density values of the bins of each color are obviously wrong.
I thought over this issue for a while. The data can't be wrong for the first histogram was normal. It should be something in ggplot2 or geom_histogram function. I googled "geom_histogram density fill" and couldn't find much help.
I want the end product to look like:
Separated by colors as you see in the second histogram
Size and shape identical to the first histogram
The vertical axis being density
How would you deal with issue?
I think what you may want is this:
ggplot(df, aes(x = x, fill=b)) +
geom_histogram()
Rather than the density. As mentioned above the density is asking for extra calcuations.
One thing that is important (in my opinion) is that histograms are graphs of one variable. As soon as you start adding data from other variables you start to change them more into bar charts or something else like that.
You will want work on setting the axis manually if you want it to range from 0 to .4.
The solution is to hand-compute density like this (instead of using the built-in ggplot2 version):
library(ggplot2)
# Generate test data
set.seed(42)
x <- rnorm(10000,0,1)
df <- data.frame(x=x, b=x>1)
ggplot(df, aes(x = x, fill=b)) +
geom_histogram(mapping = aes(y = ..count.. / (sum(..count..) * ..width..)))
when you provide a column name for the fill parameter in ggplot it groups varaiables and plots them according to each group with a unique color.
if you want a single color for the plot just specify the color you want:
FIXED
ggplot(df, aes(x = x)) +
geom_histogram(aes(y=..density..),fill="Blue")
In trying to color my stacked histogram according to a factor column; all the bars have a "green" roof? I want the bar-top to be the same color as the bar itself. The figure below shows clearly what is wrong. All the bars have a "green" horizontal line at the top?
Here is a dummy data set :
BodyLength <- rnorm(100, mean = 50, sd = 3)
vector <- c("80","10","5","5")
colors <- c("black","blue","red","green")
color <- rep(colors,vector)
data <- data.frame(BodyLength,color)
And the program I used to generate the plot below :
plot <- ggplot(data = data, aes(x=data$BodyLength, color = factor(data$color), fill=I("transparent")))
plot <- plot + geom_histogram()
plot <- plot + scale_colour_manual(values = c("Black","blue","red","green"))
Also, since the data column itself contains color names, any way I don't have to specify them again in scale_color_manual? Can ggplot identify them from the data itself? But I would really like help with the first problem right now...Thanks.
Here is a quick way to get your colors to scale_colour_manual without writing out a vector:
data <- data.frame(BodyLength,color)
data$color<- factor(data$color)
and then later,
scale_colour_manual(values = levels(data$color))
Now, with respect to your first problem, I don't know exactly why your bars have green roofs. However, you may want to look at some different options for the position argument in geom_histogram, such as
plot + geom_histogram(position="identity")
..or position="dodge". The identity option is closer to what you want but since green is the last line drawn, it overwrites previous the colors.
I like density plots better for these problems myself.
ggplot(data=data, aes(x=BodyLength, color=color)) + geom_density()
ggplot(data=data, aes(x=BodyLength, fill=color)) + geom_density(alpha=.3)
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 an working with ggplot. I want to desine a graphic with ggplot. This graphics is with two continuous variables but I would like to get a graphic like this:
Where x and y are the continuous variables. My problem is I can't get it to show circles in the line of the plot. I would like the plot to have circles for each pair of observations from the continuous variables. For example in the attached graphic, it has a circle for pairs (1,1), (2,2) and (3,3). It is possible to get it? (The colour of the line doesn't matter.)
# dummy data
dat <- data.frame(x = 1:5, y = 1:5)
ggplot(dat, aes(x,y,color=x)) +
geom_line(size=3) +
geom_point(size=10) +
scale_colour_continuous(low="blue",high="red")
Playing with low/high will change the colours.
In general, to remove the legend, use + theme(legend.position="none")