Why are the colors wrong on this ggplot?
Colours can be controlled on an individual layer basis (i.e. the colour = XYZ) variable, however, these will not appear in any legend. Legends are produced when you have an aesthetic (i.e. in this case colour aesthetic) mapped to a variable in your data, in which case, you need to instruct how to to represent that specific mapping. If you do not specify explicitly, ggplot2 will try to make a best guess (say in the difference between discrete and continuous mapping for factor data vs numeric data). There are many options available here, including (but not limited to): scale_colour_continuous
, scale_colour_discrete
, scale_colour_brewer
, scale_colour_manual
.
By the sounds of it, scale_colour_manual
is probably what you are after, note that in the below I have mapped the 'variable' column in the data to the colour aesthetic, and in the 'variable' data, the discrete values [PREV-A to PREV-F,Today] exists, so now we need to instruct what actual colour 'PREV-A','PREV-B',...'PREV-F' and 'Today' represents.
Alternatively, If the variable column contains 'actual' colours (i.e. hex '#FF0000'
or name 'red'
) then you can use scale_colour_identity
. We can also create another column of categories ('Previous','Today') to make things a little easier, in which case, be sure to introduce the 'group' aesthetic mapping to prevent series with the same colour (which are actually different series) being made continuous between them.
First prepare the data, then go through some different methods to assign colours.
# Put data as points 1 per row, series as columns, start with
# previous days
df.new = as.data.frame(t(previous_volumes))
#Rename the series, for colour mapping
colnames(df.new) = sprintf("PREV-%s",LETTERS[1:ncol(df.new)])
#Add the times for each point.
df.new$Times = seq(0,1,length.out = nrow(df.new))
#Add the Todays Volume
df.new$Today = as.numeric(todays_volume)
#Put in long format, to enable mapping of the 'variable' to colour.
df.new.melt = reshape2::melt(df.new,'Times')
#Create some colour mappings for use later
df.new.melt$color_group = sapply(as.character(df.new.melt$variable),
function(x)switch(x,'Today'='Today','Previous'))
df.new.melt$color_identity = sapply(as.character(df.new.melt$variable),
function(x)switch(x,'Today'='red','grey'))
And here are a few different ways of manipulating the colours:
#1. Base plot + color mapped to variable
plot1 = base + geom_path(aes(color=variable)) +
ggtitle("Plot #1")
#2. Base plot + color mapped to variable, Manual scale for Each of the previous days and today
colors = setNames(c(rep('gray',nrow(previous_volumes)),'red'),
unique(df.new.melt$variable))
plot2 = plot1 + scale_color_manual(values = colors) +
ggtitle("Plot #2")
#3. Base plot + color mapped to color group
plot3 = base + geom_path(aes(color = color_group,group=variable)) +
ggtitle("Plot #3")
#4. Base plot + color mapped to color group, Manual scale for each of the groups
plot4 = plot3 + scale_color_manual(values = c('Previous'='gray','Today'='red')) +
ggtitle("Plot #4")
#5. Base plot + color mapped to color identity
plot5 = base + geom_path(aes(color = color_identity,group=variable))
plot5a = plot5 + scale_color_identity() + #Identity not usually in legend
ggtitle("Plot #5a")
plot5b = plot5 + scale_color_identity(guide='legend') + #Identity forced into legend
ggtitle("Plot #5b")
gridExtra::grid.arrange(plot1,plot2,plot3,plot4,
plot5a,plot5b,ncol=2,
top="Various Outputs")
So given your question, #2 or #4 is probably what you are after, using #2, we can add another layer to render the value of the last points:
#Additionally, add label of the last point in each series.
df.new.melt.labs = plyr::ddply(df.new.melt,'variable',function(df){
df = tail(df,1) #Last Point
df$label = sprintf("%.2f",df$value)
df
})
baseWithLabels = base +
geom_path(aes(color=variable)) +
geom_label(data = df.new.melt.labs,aes(label=label,color=variable),
position = position_nudge(y=1.5),size=3,show.legend = FALSE) +
scale_color_manual(values=colors)
print(baseWithLabels)
If you want to be able to distinguish between the various 'PREV-X' lines, then you can also map linetype
to this variable and/or make the label geometry more descriptive, below demonstrates both modifications:
#Add labels of the last point in each series, include series info:
df.new.melt.labs2 = plyr::ddply(df.new.melt,'variable',function(df){
df = tail(df,1) #Last Point
df$label = sprintf("%s: %.2f",df$variable,df$value)
df
})
baseWithLabelsAndLines = base +
geom_path(aes(color=variable,linetype=variable)) +
geom_label(data = df.new.melt.labs2,aes(label=label,color=variable),
position = position_nudge(y=1.5),hjust=1,size=3,show.legend = FALSE) +
scale_color_manual(values=colors) +
labs(linetype = 'Series')
print(baseWithLabelsAndLines)
ggplot wrong color assignment
As you want to supply color names to argument colour=
and display also a legend for this argument, you should add scale_colour_identity()
to your last line in function. This scale ensures that values supplied will be interpreted as actual color values. Adding of argument breaks=cols_hex
in function scale()
will ensure ordering of names in legend.
ggplot(NULL) +
geom_point(data=data, aes(x=x, y=y, colour=cols_hex), size=size, alpha=alpha) +
scale_colour_identity(guide="legend",breaks=cols_hex)
wrong colour assignment
As you are providing colors by their name and not mapping to variable, colour=
should be placed outside the aes()
.
ggplot(x, aes(x = wages)) +
geom_density(alpha=.4, colour = "darkgrey", fill = "darkgrey") +
geom_vline(data = x, aes(xintercept = mean(x$wages)),colour = "green",
linetype = 1, size = 0.5)+
geom_vline(data = x, aes(xintercept = median(x$wages)),colour = "blue",
linetype = 1, size = 0.5) +
geom_vline(data = x, aes(xintercept = mean(x$wages)+1*sd(x$wages)),colour = "red",
linetype = 1, size = 0.5)+
xlim(c(0,3))
R ggplot changing the color and legend sequences in legend
If you want to assign, as you did, a color to a whole geom
, just put colour="red"
outside of the aes()
. But then the colour will not appear in legend as it is not mapped to any factor.
The correct way to do this is to modify your data.frame
so that Comp_apply
and L1_25
appears as two modalities of the same factor (i.e. in the same column). I can't do it for you as your data are not provided.
Then you would have to call geom_point
and geom_line
only once. Provide data and I update my answer.
Wrong colors appearing when getting the color from a data frame to geom_segment
Use scale_colour_identity()
, e.g.
library(ggplot2)
dd <- data.frame(x=0:1,y=0:1,outcome=c("#000000","#FF0000"))
ggplot(dd,aes(x,y,colour=outcome)) + geom_point() + scale_colour_identity()
ggplot color scale rendering incorrectly
Is this the plot you are looking for? Use n.breaks=12
Replace
scale_fill_stepsn(breaks=data_levels, colors=level_colors, limits=c(-3,3), labels=scales::label_number(accuracy=0.1)) +
with
scale_fill_stepsn(n.breaks=12, colors=level_colors, limits=c(-3,3), labels=scales::label_number(accuracy=0.1)) +
When I run your code I get this plot.
Related Topics
Ggplot2 Ggsave Function Causes Graphics Device to Not Display Plots
Calculate a 2D Spline Curve in R
Joining Two Data.Tables in R Based on Multiple Keys and Duplicate Entries
Using Mutate Rowwise Over a Subset of Columns
Creating an Equal Distance Spatial Grid in R
Return Rows Establishing a "Closest Value To" in R
How to Extract Variable Names from a Netcdf File in R
Ggplot2: Making Changes to Symbols in The Legend
Aws Dynamodb Support for "R" Programming Language
How to Force Ggplot's Geom_Tile to Fill Every Facet
Plot Weighted Frequency Matrix
Small Ggplot Object (1 Mb) Turns into 7 Gigabyte .Rdata Object When Saved
Count Number of Values in Row Using Dplyr
Ifelse Assignment in Data.Table
Cannot Install R Tseries, Quadprog ,Xts Packages in Linux
R: How to Expand a Row Containing a "List" to Several Rows...One for Each List Member