How can I show the dots colored using the mosaic package to do a dotplot?
library(mosaic)
n=500
r =rnorm(n)
d = data.frame( x = sample(r ,n= 1,size = n, replace = TRUE), color = c(rep("red",n/2), rep("green",n/2)))
dotPlot(d$x,breaks = seq(min(d$x)-.1,max(d$x)+.1,.1))
right now all the dots are blue but I would like them to be colored according to the color column inthe data table
If you are still interested in a mosaic/lattice solution rather than a ggplot2 solution, here you go.
dotPlot( ~ x, data = d, width = 0.1, groups = color,
par.settings=list(superpose.symbol = list(pch = 16, col=c("green", "red"))))
resulting plot
Notice also
as with ggplot2, the colors are not determined by the values in your color variable but by the theme. You can use par.settings to modify this on the level of a plot or trellis.par.set() to change the defaults.
it is preferable to use a formula and data = and to avoid the $ operator.
you can use the width argument rather than breaks if you want to set the bin width. (You can use the center argument to control the centers of the bins if that matters to you. By default, 0 will be the center of a bin.)
You need to add stackgroups=TRUE so that the two different colors aren't plotted on top of each other.
n=20
set.seed(15)
d = data.frame(x = sample(seq(1,10,1), n, replace = TRUE),
color = c(rep("red",n/2), rep("green",n/2)))
table(d$x[order(d$x)])
length(d$x[order(d$x)])
binwidth= 1
ggplot(d, aes(x = x)) +
geom_dotplot(breaks = seq(0.5,10.5,1), binwidth = binwidth,
method="histodot", aes(fill = color),
stackgroups=TRUE) +
scale_x_continuous(breaks=1:10)
Also, ggplot uses its internal color palette for the fill aesthetic. You'd get the same colors regardless of what you called the values of the "color" column in your data. Add scale_fill_manual(values=c("green","red")) if you want to set the colors manually.
Related
I've been trying this out but I cannot find a solution. The best I can do is plotting the first 15846 values in 1 colour and then using the lines() function to add the remaining 841 points. But these then appear at the start of the graph and does not continue from the 15846th datapoint.
str(as.numeric(sigma.in.fr))
num [1:15846] 0.000408 0.000242 0.000536 0.000274 0.000476 ...
str(as.numeric(sigma.out.fr))
num [1:841] 0.002558 0.000428 0.000255 0.000549 0.00028 ...
plot(as.numeric(sigma.in.fr),type="l",col=c("tomato4"))
lines(as.numeric(sigma.out.fr), type="l",col="tomato1")
This returns the plot below:
Lets make some dummy data to demonstrate:
sigma.ins.fr = sin((1:800)/20) + rnorm(800)
sigma.outs.fr = sin((801:1000)/20) + rnorm(200)
Now, put all the data together into a single sequence
sigma.all = c(sigma.ins.fr, sigma.outs.fr)
And create an x vector which simply counts along the data. We'll need this in the segments call below.
x = seq_along(sigma.all)
Now create a vector of colors for the trace. It is the same length as the full data, with a color for each segment.
cols = c(rep("tomato4", length(sigma.ins.fr)), rep("blue", length(sigma.outs.fr)))
Now create a blank canvass on which to draw the data.
plot(sigma.all, type="l", col=NA)
At last, we can plot the data. Unfortunately, lines does not allow for a separate color in different segments. So instead we can use segments
segments(head(x,-1), head(sigma.all,-1), x[-1], sigma.all[-1], type="l", col=cols)
Or, if you really prefer to use two separate traces uning lines, then we can achieve this by adding the x coordinates to each call:
plot(sigma.all, type="l", col=NA)
lines(seq_along(sigma.ins.fr), sigma.ins.fr, col=c("tomato4"))
lines(seq_along(sigma.outs.fr) + length(sigma.ins.fr), sigma.outs.fr, col="tomato1")
Please provide a reproducible example. Using the packages ggplot2 and dplyr you can do something like:
df <- tibble(x = seq(1,1000, 1), y = seq(1, 500.5, 0.5))
ggplot() +
geom_line(data = df %>% filter(x < 800),
aes(x = x, y = y), color = "red", size =2) +
geom_line(data = df %>% filter(x >= 800),
aes(x = x, y = y),
color = "black", size = 2)
Note that I put the cut off at 800 (as I only created 1000 points), but you can easily change that.
So what I do is putting the data in geom_line, as you can also use this if you have different dataframes (with overlapping x and y) you want to plot in the same graph. However, I do filter the data at different points, so that different lines are drawn by the geom_line.
I have a code snippet that shows different month numbers with corresponding seasons. I want to represent it as a bar graph in R with the bars having colors corresponding to the seasons. Please help.
month<-c(1:12)
season<-c('Winter','Spring','Spring','Summer','Summer','Summer','Rainy','Rainy','Rainy','Autumn','Autumn','Winter')
freq<-c(5,10,15,2,13,4,7,9,8,6,12,10)
df<-data.frame(month,season,freq)
df$color<-factor(df$season,labels = RColorBrewer::brewer.pal(length(unique(df$season)),name = 'Set1'))
barplot(df[,3],names.arg=df[,1],
xlab='Month',ylab='Maximum Frequency',
main='Months',
col=df$color,col.main='Blue')
legend("topright", cex=0.6,ncol=2,text.width = 1.6,bty = 'n',
x.intersp = .2,y.intersp = .59,box.lwd = 0,
legend = unique(df[,2]),
fill = df[,4])
Changing name to other palette names are not changing the colors. What else can be done. Please help.
You are messing up with factors. Here's the correct code (explanation in the code) :
month<-c(1:12)
season<-c('Winter','Spring','Spring','Summer','Summer',
'Summer','Rainy','Rainy','Rainy','Autumn','Autumn','Winter')
freq<-c(5,10,15,2,13,4,7,9,8,6,12,10)
df<-data.frame(month,season,freq)
# here we gets the colors for unique seasons
palette <- RColorBrewer::brewer.pal(length(unique(df$season)),name = 'Set1')
# here we're mapping each season with a color, exploiting the fact
# that factors are integers and we use them as indexes in the palette
# ("as.factors" is not really necessary here because season column is already factors)
df$color <- palette[as.factor(df$season)]
barplot(df[,3],names.arg=df[,1],
xlab='Month',ylab='Maximum Frequency',
main='Months',
col=df$color,col.main='Blue')
# here we need to associate a fill color for each unique season;
# we're doing this using "duplicated" function
legend("topright", cex=0.6,ncol=2,text.width = 1.6,bty = 'n',
x.intersp = .2,y.intersp = .59,box.lwd = 0,
legend = df$season[!duplicated(df$season)],
fill = df$color[!duplicated(df$season)])
I want to show the added line via geom_abline in the legend since the bar chart is denoted in the x axis labels.
How embarrassing, not sure how i forgot toy data. I also cleaned up the example making sure i was running the most up to date version of R and ggplot (and reshape!) I forgot how it can make a difference sometimes
The end product is a bar chart with the added line (indicating the average) with this information showing in the legend, so a red dotted line that says "County Average".
library(ggplot2)
DataToPlot.. <- data.frame(UGB = c("EUG","SPR","COB","VEN"),
Rate = c( 782, 798,858,902))
ggplot(DataToPlot.. ,y = Rate, x = UGB) +
geom_bar(aes(x=UGB,y=Rate, fill = UGB),stat="identity",show.legend = FALSE) +
scale_fill_brewer(palette="Set3") +
geom_abline(aes(intercept = 777, slope = 0), colour = "red",
size = 1.25, linetype="dashed",show.legend = TRUE)
After playing around for awhile (it was not as easy as I expected) I used this:
library(ggplot2)
DataToPlot.. <- data.frame(UGB = c("EUG","SPR","COB","VEN"),
Rate = c( 782, 798,858,902))
x <- c(0.5,nrow(DataToPlot..)+0.5)
AvgLine.. <- data.frame(UGB=x,Rate=777,avg="777")
ggplot(DataToPlot.. ,y = Rate, x = UGB) +
geom_bar(aes(x=UGB,y=Rate, fill = UGB),stat="identity",show.legend=TRUE ) +
scale_fill_brewer(palette="Set3") +
geom_line(data=AvgLine..,aes(x=UGB,y=Rate,linetype=avg),
colour = "red", size = 1.25) +
scale_linetype_manual(values=c("777"="dashed")) +
# make the guide wider and specify the order
guides(linetype=guide_legend(title="Country Average",order=1,keywidth = 3),
color=guide_legend(title="UGB",order=2))
Note I couldn't coerce geom_abline to make its own guide. I had to create a dataframe. The x-coordinates for that line are basically the factor values, and I adjusted them to reach beyond the edges of the plot.
To get this:
I've found many examples describing the assignment of alpha when in a ggplot2 line like so:
scale_alpha( variable, trans = reverse)
ref
However, is there a method to simply invert the scale in aes() inside the geom_*()?
Something like:
geom_point(aes(colour=variableA, alpha=REVERSE(variableB))
(This is a very old question, but I had the same issue and couldn't find an answer. The previous solution by hugh-allan is, as indicated in the Edit note, producing an incorrect legend.)
The settings of the scale should really be in the scale_alpha* parameter. That's where you manage this. The geoms are used for adding the data or setting a style for all points, not tuning a specific scale (otherwise, it would need to be inside the aes() mapping).
To be clear, there are two options in current versions of ggplot2 (using version 3.3.5):
tibble(x = 1:10, y = 1) %>%
ggplot(aes(x, y, alpha = x) +
geom_point(size = 5) +
scale_alpha(trans = reverse_trans())
or, probably more in line with current ggplot documentation:
scale_alpha(range = c(1, 0.1))
i.e., reversing the range of the alpha scale (the default is range = c(1, 0.1)).
If I understand the question correctly, you want to reverse the scale by which alpha is assigned inside a geom...?
For example, by default lower values of x will have lower values of alpha, and appear lighter:
# sample data
tibble(
x = 1:10,
y = 1,
) %>%
ggplot(aes(x, y, alpha = x))+
geom_point(size = 5)
You can reverse it so lower values of x are darker, by using sort() inside aes():
tibble(
x = 1:10,
y = 1,
) %>%
ggplot(aes(x, y, alpha = sort(x, decreasing = TRUE)))+
geom_point(size = 5)
Edit: just realised the legend is incorrect. I guess it's ok if you don't include the legend.
Warning.... very novice question follows:
I am trying to plot a fairly regular distribution of several thousand (X,Y) points each associated with a value, let's call Z, which varies very irregularly between, say, -20 to +20. I am not interested in smoothing; I want the point Z values to plot according to a smoothly varying color palette much like Gnuplot can do with the proper smooth color palette. I've tried base R, ggplot2, and latticeExtra, and as best I can, I can come up with the following which does almost what I want:
library(lattice)
library(latticeExtra)
library(colorRamps)
df = read.table(file"whatever", header=T)
levelplot(Z~X*Y, df, panel=panel.levelplot.points, cex=0.2,
col.regions=colorRampPalette(c("red","white","blue"))(50))
One data point looks like: 1302525 225167 -3.5
When I plot my dataframe with the "50" in the last code line as 3, I get the predictable R recycle behavior of the red, white, and blue colors repeating five times with the 16th color bar segment white. Changing the 3 to a 7 causes more shades of red and blue creating 2 repeat color range segments with two reddish colors left over as the color range tries to recycle. This suggests making this number larger causes a finer graduation of colors. But if I put in a number greater than 16, that's all I get, 16 colored segments, evenly changing from red, to white, to blue. But I'd like the color scale even finer, and in a perfect world, force a Z of zero to be the white color.
My experience so far with R is when I can't do something as simple as this, I'm missing a very fundamental concept. What is it?
As far as lattice is concerned, you can set up your colors palette with RColorBrewer (or even colorspace). Using the example provided by #Chase, but with positive value for z:
dat <- data.frame(x = rnorm(1000), y = rnorm(1000), z = sample(0:40, 1000, TRUE))
library(RColorBrewer)
# see, e.g.
# display.brewer.all(9, type="seq")
# display.brewer.pal(11, "RdBu")
my.col <- colorRampPalette(brewer.pal(11, "RdBu"))(diff(range(dat$z)))
xyplot(y ~ x, data=dat, col=my.col[dat$z], pch=19, alpha=.5)
Note that it is also necessary here to increase the range of available colors by interpolation. Also, with levelplot(), you might want to play with cut= and pretty=.
Have you looked at scale_gradient in ggplot? Or scale_brewer for discrete colours? Here's an example of scale_gradient
dat <- data.frame(x = rnorm(1000), y = rnorm(1000), z = sample(-20:20, 1000, TRUE))
p <- ggplot(dat, aes(x, y, colour = z)) + geom_point()
p + scale_colour_gradient()
p + scale_colour_gradient(low = "red", high = "blue")
p + scale_colour_gradient2(low = "red", mid = "white", high = "blue")
The "concept" you are missing is the at argument to levelplot() which defines the breakpoints between colour levels and/or contour lines. The default is pretty(z) which results in only a few levels. You can set at to be a sequence covering the range of values you want.
library(latticeExtra)
dat <- data.frame(x = rnorm(1000), y = rnorm(1000), z = rnorm(1000, mean = 1))
## for centering the colour key around zero
maxz <- max(abs(dat$z))
levelplot(z ~ x * y, dat, at = seq(-maxz, maxz, length = 100),
panel = panel.levelplot.points, par.settings = custom.theme.2())