geom_abline legend - How can I add abline text legend - r

I'm trying to build charts control. I want to explicit that green line (abline1) is central line and red line (abline2 and abline3) are the limits control.
Can you help me?
library(ggplot2)
amostra <- rnorm(30, 10)
qplot(y = amostra, x = seq_along(amostra), ylim = c(5,15), main = "Gráfico de Controle", xlab = 'Período', ylab = 'Valores') + geom_line() +
geom_abline(aes(slope=0, intercept=10), colour = 'green', size=1) +
geom_abline(aes(slope=0, intercept=7), colour='red', size = 1) +
geom_abline(aes(slope=0, intercept=13), colour='red', size = 1) +
theme(plot.title = element_text(hjust = 0.5))

If you want a legend, then you need an aesthetic mapping. Move color in the aes() and add a scale_color_identity(). You can do this with
qplot(y = amostra, x = seq_along(amostra), ylim = c(5,15), main = "Gráfico de Controle", xlab = 'Período', ylab = 'Valores') + geom_line() +
geom_abline(aes(slope=0, intercept=10, colour = 'green'), size=1) +
geom_abline(aes(slope=0, intercept=7, colour='red'), size = 1) +
geom_abline(aes(slope=0, intercept=13, colour='red'), size = 1) +
theme(plot.title = element_text(hjust = 0.5)) +
scale_color_identity(labels=c("central","limits"), guide="legend")

This is a rather bad hack, but to force the lines to be in the legend, you could try to draw them using the geom_errorbarh() function. This will plot errorbars. If you make them as wide as the plot while setting the plot width explicitly with scale_x_continuous(), you can have horizontal bars that are shown in figure legend.

Related

Add a custom Axis label with unique color and size

I have the following chart:
df<- data.frame(year=c(1960,1961,1962),value=c(10,18,20))
ggplot(df,aes(x=year,y=value))+geom_col()+
geom_hline(yintercept =18,linetype="dashed", color = "red",size=1)
I would like to add a red label in the Y axis with the text "Actual Value" where the red line is.
I know i cann add the text changing breaks, but then i could not have the new text in red.
There is any way I can change only that one's colour and size but not the other legends in the axis?
I am looking for something like this:
Thank you!
Here's an approach with annoate:
Use annoate to specify the text you want to plot. Provide x = and y = arguments to indicate where to plot.
Use coord_cartesian with clip = 'off' to plot outside the plot area and use xlim = to fix the x axis to the data rather than also including the coordinates of the annotate call.
Use plot.margin to widen the left margin so there's room for the text.
You may need to modify the xlim and x = arguments to get it just right.
ggplot(df,aes(x=year,y=value)) +
geom_col() +
geom_hline(yintercept =18,linetype="dashed", color = "red",size=1) +
coord_cartesian(clip = 'off',
xlim = c(1959.5,1962.5)) +
annotate(geom = "text", y = 18, x = 1959.1, color = "red", label = "Actual Value") +
theme(plot.margin = unit(c(1,1,1,3), "lines"))
Edit:
You can use \n in the label to make the text appear on two lines.
ggplot(df,aes(x=year,y=value)) +
geom_col() +
geom_hline(yintercept =18,linetype="dashed", color = "red",size=1) +
coord_cartesian(clip = 'off',
xlim = c(1959.5,1962.5)) +
annotate(geom = "text", y = 18, x = 1959.2, color = "red", label = "Actual\nValue") +
theme(plot.margin = unit(c(1,1,1,2), "lines"))
You can use geom_text :
library(ggplot2)
ggplot(df,aes(x=year,y=value))+geom_col()+
geom_hline(yintercept =18,linetype="dashed", color = "red",size=1) +
geom_text(aes(1960,18,label = 'Actual Value', vjust = -1),
color = 'red', size = 8)

Problem: qqplot legend different linetypes

legend <- c("score" = "black", "answer" = "red")
plot <- df_l %>% ggplot(aes(date, score, color = "score")) + geom_line() +
geom_vline(aes(xintercept = getDate(df_all %>% filter(name == List[5])), color = "answer"), linetype = "dashed", size = 1,) +
scale_color_manual(name = "Legend", values = legend) +
scale_x_date(labels = date_format("%m/%y"), breaks = date_breaks("months")) +
theme(axis.text.x = element_text(angle=45)) +
labs(title = "", x = "", y = "", colors = "Legend")
I get the result above and could not figure out how to resolve the problem that in the legend always both lines are mixed up. One legend should of course show the slim black line only and the other the dashed black line. Thanks in advance!
The issue you have is that geom_vline results in a legend item that is a vertical line and geom_line gives you a horizontal line item. One solution is to create the legend kind of manually by specifying the color= aesthetic in geom_line... but not in geom_vline. You can then create a kind of "dummy" geom with geom_blank that serves as a holding object for the aesthetics of color=. You can then specify the colors for both of those items via scale_color_manual. Here's an example:
set.seed(12345)
df <- data.frame(x=1:100,y=rnorm(100))
ggplot(df, aes(x,y)) + theme_bw() +
geom_line(aes(color='score')) +
geom_vline(aes(xintercept=4), linetype=2, color='red', show.legend = FALSE) +
geom_blank(aes(color='my line')) +
scale_color_manual(name='Legend', values=c('my line'='red','score'='black'))
That creates the one legend for color... but unfortunately "my line" is solid red, when it should be dashed. To fix that, you just apply the linetype= aesthetic in the same way.
ggplot(df, aes(x,y)) + theme_bw() +
geom_line(aes(color='score', linetype='score')) +
geom_vline(aes(xintercept=4), linetype=2, color='red', show.legend = FALSE) +
geom_blank(aes(color='my line', linetype='my line')) +
scale_linetype_manual(name='Legend', values=c('my line'=2,'score'=1)) +
scale_color_manual(name='Legend', values=c('my line'='red','score'='black'))

Inserting a custom label on the y axis in ggplot2

Using ggplot2 in R, i'm trying to insert a red line that indicates the average of a chain. I would like to insert the average value close to the line so that it was not necessary to "deduct" the value.
I tried to use a negative coordinate for x, but it did not work, the value is behind the axis.
ggplot(data = chain.fmBC) +
geom_line(aes(1:25000, chain.fmBC$V2)) +
labs(y = "", x = "") +
labs(caption= "Bayes C") +
geom_hline(yintercept = mean(chain.fmBC$V2), colour = "RED") +
geom_text(label = round(mean(chain.fmBC$V2), 2),
x = 0, y = min(chain.fmBC$V2), colour = "RED")
this is a picture of my graph:
How could I put the value that is in red (media) to the left of the y-axis of the graph, between 0 and 5000, as if it were a label of the y-axis?
You can set your y axis ticks manually so that it includes the mean value. This will give you a nicely positioned annotation. If the real issue is the colored axis label, unfortunately this does not solve that
Example:
ggplot(mtcars, aes(disp)) +
geom_histogram() +
geom_hline(yintercept = 0.5, color = "red") +
scale_y_continuous(breaks = c(0,0.5,1,2,3,4)) +
theme(axis.text.y = element_text())
Which will give you this:
I was successful following the suggestions, I would like to share.
I got good help here.
cadeia.bayesc <- ggplot(data = chain.fmBC) + geom_line(aes(1:25000, chain.fmBC$V2)) +
theme(plot.margin = unit(c(0.5,0.5,0.5,1), "lines")) + # Make room for the grob
labs(y = "", x = "") + labs(caption= "Bayes C") +
cadeia.bayesc <- cadeia.bayesc + geom_hline(yintercept = mean(chain.fmBC$V2), colour = "RED") # insert the line
cadeia.bayesc <- cadeia.bayesc + annotation_custom( # grid::textgrob configure the label
grob = textGrob(label = round(mean(chain.fmBC$V2),2), hjust = 0, gp = gpar(cex = .7, col ="RED")),
xmin = -6000, xmax = -100, ymin = mean(chain.fmBC$V2), ymax = mean(chain.fmBC$V2))
# Code to override clipping
cadeia.bayesc.plot <- ggplot_gtable(ggplot_build(cadeia.bayesc))
cadeia.bayesc.plot$layout$clip[cadeia.bayesc.plot$layout$name == "panel"] <- "off"
grid.draw(cadeia.bayesc.plot)
result (https://i.imgur.com/ggbuNuK.jpg)

Add geom_hline to legend

After searching the web both yesterday and today, the only way I get a legend working was to follow the solution by 'Brian Diggs' in this post:
Add legend to ggplot2 line plot
Which gives me the following code:
library(ggplot2)
ggplot()+
geom_line(data=myDf, aes(x=count, y=mean, color="TrueMean"))+
geom_hline(yintercept = myTrueMean, color="SampleMean")+
scale_colour_manual("",breaks=c("SampleMean", "TrueMean"),values=c("red","blue"))+
labs(title = "Plot showing convergens of Mean", x="Index", y="Mean")+
theme_minimal()
Everything works just fine if I remove the color of the hline, but if I add a value in the color of hline that is not an actual color (like "SampleMean") I get an error that it's not a color (only for the hline).
How can adding a such common thing as a legend big such a big problem? There much be an easier way?
To create the original data:
#Initial variables
myAlpha=2
myBeta=2
successes=14
n=20
fails=n-successes
#Posterior values
postAlpha=myAlpha+successes
postBeta=myBeta+fails
#Calculating the mean and SD
myTrueMean=(myAlpha+successes)/(myAlpha+successes+myBeta+fails)
myTrueSD=sqrt(((myAlpha+successes)*(myBeta+fails))/((myAlpha+successes+myBeta+fails)^2*(myAlpha+successes+myBeta+fails+1)))
#Simulate the data
simulateBeta=function(n,tmpAlpha,tmpBeta){
tmpValues=rbeta(n, tmpAlpha, tmpBeta)
tmpMean=mean(tmpValues)
tmpSD=sd(tmpValues)
returnVector=c(count=n, mean=tmpMean, sd=tmpSD)
return(returnVector)
}
#Make a df for the data
myDf=data.frame(t(sapply(2:10000, simulateBeta, postAlpha, postBeta)))
Given solution works in most of the cases, but not for geom_hline (vline). For them you usually don't have to use aes, but when you need to generate a legend then you have to wrap them within aes:
library(ggplot2)
ggplot() +
geom_line(aes(count, mean, color = "TrueMean"), myDf) +
geom_hline(aes(yintercept = myTrueMean, color = "SampleMean")) +
scale_colour_manual(values = c("red", "blue")) +
labs(title = "Plot showing convergens of Mean",
x = "Index",
y = "Mean",
color = NULL) +
theme_minimal()
Seeing original data you can use geom_point for better visualisation (also added some theme changes):
ggplot() +
geom_point(aes(count, mean, color = "Observed"), myDf,
alpha = 0.3, size = 0.7) +
geom_hline(aes(yintercept = myTrueMean, color = "Expected"),
linetype = 2, size = 0.5) +
scale_colour_manual(values = c("blue", "red")) +
labs(title = "Plot showing convergens of Mean",
x = "Index",
y = "Mean",
color = "Mean type") +
theme_minimal() +
guides(color = guide_legend(override.aes = list(
linetype = 0, size = 4, shape = 15, alpha = 1))
)

Modify Legend using ggplot2 in R

I'm currently using the ggplot package to plot a histogram of normal variates with a N(0, 1) density overlay. I'm very new to this package and the code I'm using is
x = rnorm(1000)
qplot(x, geom = 'blank') +
geom_histogram(aes(y = ..density.., colour = 'Histogram'), legend = FALSE,
binwidth = 0.5, fill = "blue") +
stat_function(fun = dnorm, aes(colour = 'Density'))+
scale_x_continuous('x', limits = c(-4, 4))+
opts(title = "Histogram with Overlay")+
scale_colour_manual(name = 'Legend', values = c('darkblue', 'red')) +
scale_y_continuous('Frequency')+
opts(legend.key=theme_rect(fill="white",colour="white"))+
opts(legend.background = theme_rect())
This code produces the following diagram. How do I change the legend so that the line representing the histogram is replaced with a filled blue box (that represents the bars of the histogram)? Thank You!
Maybe something like this...
dat = data.frame(x=rnorm(1000))
ggplot(dat,aes(x=x)) +
geom_histogram(aes(y=..density..,fill="Histogram"),binwidth=0.5) +
stat_function(fun = dnorm, aes(colour= "Density")) +
scale_x_continuous('x', limits = c(-4, 4)) +
opts(title = "Histogram with Overlay") +
scale_fill_manual(name="",value="blue") +
scale_colour_manual(name="",value="red") +
scale_y_continuous('Frequency')+
opts(legend.key=theme_rect(fill="white",colour="white"))+
opts(legend.background = theme_blank())
Note: Since version 0.9.2 opts has been replaced by theme. So for example, the last two lines above would be:
theme(legend.key = element_rect(fill = "white",colour = "white")) +
theme(legend.background = element_blank())

Resources