I would just like to simply add an annotation to my ggplot with the exponential function on it like this graph:
excel graph
Here is the data:Data
Here is the code I used thus far:
dfplot<-ggplot(data, aes(dilution.factor,Concentation)) +
geom_point(size=3)+ geom_smooth(method="auto",se=FALSE, colour="black")+
scale_y_continuous(breaks=seq(0,14,by=2))
dfplot2<-dfplot+labs(x=('Dilution Factor'), y=expression('Concentration' ~
(ng/mu*L)))+
theme_bw() + theme(panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text = element_text(colour="black"),
axis.line = element_line(colour = "black"))
dfplot3<- dfplot2+annotate("text", x=3, y=10, label = "R^2 == 1",parse=TRUE)
dfplot3
dfplot4<-dfplot3+annotate("text", x=3, y=11, label =
as.character(expression("y=13.048e^-{0.697x}" ,parse=TRUE)))
dfplot4
I can get all the way up to putting the r^2 value (dfplot3)dfplot3
For some reason I cannot get it to add the exponential equation in. I keep getting this error:
Error: Aesthetics must be either length 1 or the same as the data (1): label
What am i doing wrong?
Not quite sure about the as.character(expression()) syntax you are using, but when you are parsing annotation text, ggplot2 doesn't understand the 'human' style notation shortcut of placing a number next to a letter 13.084e, you need to tell it explicitly this is multiplication. You also need == instead of =.
annotate("text", x=3, y=11, label = "y == 13.048*e^-{0.697*x}", parse =TRUE)
Edit: I see that you have included parse = TRUE inside the expression call, I think this is a mistake. To do it with expression you would write the following, but this is not in fact necessary:
annotate("text", x=3, y=11, label = as.character(expression("y == 13.048*e^-{0.697*x}")), parse = T)
Related
I am trying to label the y-axis of my graph with the Theta greek symbol and P(z) with a comma separating them. Additionally, I am tyring to label my x-axis Q(z_i) where i is a subscript. I have tried to do this a few different ways..
string <- ", P(z)"
thet <- bquote(theta)
ylab.fig2 <- paste(thet, string, sep = "")
and have done something similar with expression(theta). I use ylab.fig2 as an input in my ggplot, ylab(fig.2).
new <- ggplot(data = data.frame(x=0), aes(x=x)) +
stat_function(fun=Pz.eq, aes(colour="P(z)")) +
stat_function(fun=bid1, aes(colour="Bid Curve: House 1")) +
stat_function(fun=bid2, aes(colour="Bid Curve: House 2")) +
stat_function(fun=bid3, aes(colour="Bid Curve: House 3")) +
xlim(0,20) + ylim(0,6) +
xlab("Q(z_i)") + ylab(ylab.fig2) +
ggtitle("Figure 2: Property Choice Per Household") +
theme(panel.grid = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks.x = element_blank(),
axis.ticks.y = element_blank(),
legend.title = element_blank(),
plot.title = element_text(hjust=0.5)) +
scale_colour_manual("Groups",
values = c("darkseagreen", "darkkhaki", "darkslategray3", "firebrick"))
The bquote() and expression() both work fine if they are sole inputs but when I use paste to return the rest of the axis label the greek symbol is not output. I believe this is due to the differing class() of each object. Alternatively, if there is a way to compile LaTex in the labels that would solve both my x and y-axis issues.
This is what my graph looks like thus far...
Overall, there are three things I'm trying to accomplish with x and y-axis labels:
1) Concat greek letters with text.
2) Put bold text inside of the label (only the z vector in P(z) will be bold).
3) Place 'i' subscripts on my text.
While the question regarding Greek letters has been posted before I am looking for a solution using LaTex where I can use more than just math symbols. Using LaTex code is will allow me to solve issues 2 and 3, not just 1.
The latex2exp package is probably the easiest:
library(latex2exp)
string <- ", P(z)"
thet <- "$\\theta$"
ylab.fig2 <- TeX(paste(thet, string, sep = ""))
And then use as ... + ylab(ylab.fig2) to build the plot.
Or using bquote and expression:
library(ggplot2)
i=2
f <- bquote(expression(theta * ", " * P(bold(z))))
g <- bquote(expression(Q(z[.(i)])))
ggplot(mtcars, aes(x=hp, y=wt)) + geom_point()+
ylab(eval(f))+
xlab(eval(g))
I know this question has been asked a number of times but I think some of the underlying syntax for plotly has changed since those questions have been asked. Using ggplotly() to create a choropleth map gives the default tooltip of long, lat, group, and one of my variables from my aesthetics. I understand that tooltip maps only whats in the aesthetics. All I want to do is to customize the tooltip so it displays some of the variables in my dataset (including those not mapped to aesthetics) and not others (such as the coordinates). Below is a reproducible example and what I've tried so far. I followed the advice given in response to other questions to no avail.
#Load dependencies
library(rgeos)
library(stringr)
library(rgdal)
library(maptools)
library(ggplot2)
library(plotly)
#Function to read shapefile from website
dlshape=function(shploc, shpfile) {
temp=tempfile()
download.file(shploc, temp)
unzip(temp)
shp.data <- sapply(".", function(f) {
fp <- file.path(temp, f)
return(readOGR(".",shpfile))
})
}
austria <- dlshape(shploc="http://biogeo.ucdavis.edu/data/gadm2.8/shp/AUT_adm_shp.zip",
"AUT_adm1")[[1]]
#Create random data to add as variables
austria#data$example1<-sample(seq(from = 1, to = 100, by = 1), size = 11, replace = TRUE)
austria#data$example2<-sample(seq(from = 1, to = 100, by = 1), size = 11, replace = TRUE)
austria#data$example3<-sample(seq(from = 1, to = 100, by = 1), size = 11, replace = TRUE)
#Fortify shapefile to use w/ ggplot
austria.ft <- fortify(austria, region="ID_1")
data<-merge(austria.ft, austria, region="id", by.x = "id", by.y = "ID_1")
#Save as ggplot object
gg<-ggplot(data, aes(x = long, y = lat, fill = example1, group = group)) +
geom_polygon() + geom_path(color="black",linetype=1) +
coord_equal() +
scale_fill_gradient(low = "lightgrey", high = "darkred", name='Index') +xlab("")+ylab("") +
theme(axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank()) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black")) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))
#Plot using ggplotly
ggplotly(gg)
From here I've tried two different approaches. The most successful one of the approaches gets me there in part. I can add new variables to to the tooltip but I cannot do two things: 1) I cannot get rid of other variables already displayed by default (from the aesthetics) and 2) I cannot rename the variables something other than their column name from the dataset (for example I would like to label "example3 as "Example III"). Here is that approach:
#Save as a new ggplot object except this time add ``label = example3`` to the aesthetics
gg2<-ggplot(data, aes(x = long, y = lat, fill = example1, group = group, label = example3)) +
geom_polygon() + geom_path(color="black",linetype=1) +
coord_equal() +
scale_fill_gradient(low = "lightgrey", high = "darkred", name='Index') +xlab("")+ylab("") +
theme(axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank()) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black")) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))
#Save as plotly object then plot
gg2 <- plotly_build(gg2)
gg2
I also tried adding the following but it did nothing:
gg2$data[[1]]$text <- paste("Example I:", data$example1, "<br>",
"Example II:", data$example2, "<br>",
"Example III:", data$example3)
Any help is much appreciated!
UPDATE: I updated plotly by installing from github instead of CRAN. Using this updated version (4.0.0) I've made it apart of the way there.
gg2$x$data[[2]]$text <- paste("Example I:", data$example1, "<br>",
"Example II:", data$example2, "<br>",
"Example III:", data$example3)
gg2
What happens now simply baffles me. This adds an additional tooltip separate from the previous one. This new tooltip is exactly what I want however both of them appear -not at once but if I move my mouse around. See the two screenshots below:
Notice those tooltips are from the same unit (Tirol). Could this be a bug in the package? This does not occur when display other graphs such as a time-series instead of a map. Also note, that I assigned the label "Example I" (or II or III) and this does not show on the new tooltip I added.
UPDATE #2: I figured out that the old tooltip (with long and lat shown) only appears when hovering over the borders so I got rid of the geom_path(color="black",linetype=1) command (as to remove the borders) and now I've managed to successfully solve that problem. However, I'm still unable to modify the labels that appear in the tooltip.
UPDATE #3: I figured out how to edit the labels but FOR ONLY ONE VARIABLE. Which is nuts! Here's my workflow from start to finish:
#Load dependencies
library(rgeos)
library(stringr)
library(rgdal)
library(maptools)
library(ggplot2)
library(plotly)
#Function to read shapefile from website
dlshape=function(shploc, shpfile) {
temp=tempfile()
download.file(shploc, temp)
unzip(temp)
shp.data <- sapply(".", function(f) {
fp <- file.path(temp, f)
return(readOGR(".",shpfile))
})
}
austria <- dlshape(shploc="http://biogeo.ucdavis.edu/data/gadm2.8/shp/AUT_adm_shp.zip",
"AUT_adm1")[[1]]
#Create random data to add as variables
austria#data$example1<-sample(seq(from = 1, to = 100, by = 1), size = 11, replace = TRUE)
austria#data$example2<-sample(seq(from = 1, to = 100, by = 1), size = 11, replace = TRUE)
austria#data$example3<-sample(seq(from = 1, to = 100, by = 1), size = 11, replace = TRUE)
#Fortify shapefile to use w/ ggplot
austria.ft <- fortify(austria, region="ID_1")
data<-merge(austria.ft, austria, region="id", by.x = "id", by.y = "ID_1")
#Save as ggplot object
gg<-ggplot(data, aes(x = long, y = lat, fill = example1, group = group, text = paste("Province:", NAME_1))) +
geom_polygon(color="black", size=0.2) +
coord_equal() +
scale_fill_gradient(low = "lightgrey", high = "darkred", name='Index') +xlab("")+ylab("") +
theme(axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank()) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black")) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))
gg <- plotly_build(gg)
gg
That produces the following plot:
Notice that "Province" is now capitalized (it was not before). The trick was adding text = paste("Province:", NAME_1) to the aesthetics. HOWEVER, when I tried to add additional label changes using text2=paste("Example III:", example1), the following occurs:
Notice that it cannot render text2 the same way it renders text1. So instead I simply try adding a duplicate without the text2 like in the following: text=paste("Example III:", example1) -which produces the following odd result:
I'm beginning to think something as simple as toggling "legend" options in plotly's ggplot conversion is impossible.
UPDATE #4: So I decided to approach this another way. Instead, I decided to change the variable names themselves. I would have done this from the start, except I wasn't sure if/how ggplot2 accepts variables with spaces -i figured out `variable` that can work. So I went ahead and relabeled the variables. It works -KINDA. The problem is the text appears with the quotations marks around them. Now I need a way to get rid of these!!! Any ideas anyone? Thanks! Here is an image of what I mean by quotations in the text:
I am new to plotly too but have come across a similar problem for my ggplot2 bubble plots when using ggplotly(). I have finally found a solution that works for me and thought it might help you, too, although I haven't tried it for choropleth maps.
Your first question was to customize the tooltip so it displays some of the variables in the dataset (including those not mapped to aesthetics).
In your UPDATE#3 you introduce:text = paste("Province:", NAME_1) into your aes. If you want to add a second line of custom variables or text, just keep adding it into the brackets:text = paste("Province:", NAME_1, "Example III:", example1) To add a line break between both add <br> in the spot where you want the break to be, like:text = paste("Province:", NAME_1, "<br>", "Example III:", example1)
Your second question was to customize the tooltip so it does NOT display other (default) variables (that are mapped to aesthetics, such as the coordinates).
I found this very easy addition to the ggplotly() function that did the trick for me: ggplotly(gg, tooltip = c("text")) In my case, this removed ALL default variables that are shown in the tooltip and only showed those that are custom specified with text above. You can add other variables back in by doing ggplotly(gg, tooltip = c("text","x")) The order of the variables shown in the tooltip will be the same as the order specified in the tooltip argument. I found this documented here: https://github.com/ropensci/plotly/blob/master/R/ggplotly.R
This solution worked (in principle) for me using R 3.1.1 and plotly 3.4.13
I was trying to add a custom text annotation grob to my plot according to the website http://zevross.com/blog/2014/08/04/beautiful-plotting-in-r-a-ggplot2-cheatsheet-3. I am using this technique so that I can add the text a normalized coordinates. When I add the grob the text does not appear on the plot. I had used this procedure before and it worked like a champ. For the life of me I can not figure out why this one is not working.
Minimal example here:
len = 100
pd = data.frame(x = runif(50)*len - len/2, y = runif(50)*len - len/2)
my_grob = grobTree(textGrob('Some Text', x=0.5, y=0.5, hjust=0.5, gp=gpar(col='black', fontsize=12, fontface="italic")))
rp = ggplot() + theme_bw() +
theme(axis.text = element_blank(), axis.ticks = element_blank(), axis.title = element_blank()) +
theme(panel.grid = element_blank(), panel.border = element_blank()) +
geom_point(data = pd, aes(x = x, y = y)) +
coord_equal(xlim = c(-len/2, len/2)*1.1, ylim = c(-len/2, len/2)*1.1) +
annotation_custom(my_grob)
rp
Can anybody help me to see what I am missing here? I thought it might have been the theme alterations, but when I took them out the problem still persisted. (Yea, after saying that I could remove them from the above to make it more minimal... But I am going to leave it in for full effect). Thanks for any insight.
As was stated in the comment above by RStudent, all I needed to do was choose one of my datasets to feed to the ggplot() constructor. Although this worked, I was hopeful that I would not have to do that.
I'm trying to define this function to easily set a custom theme to a ggplot, but I'm having trouble using the functions like element_blank() dynamically.. For example, specifying whether or not to have vertical gridlines as a TRUE/FALSE argument:
qplot(data=df, x=quarter, y=value, geom="line") +
style(grid.vertical = F)
style = function (grid.vertical = T) {
(theme_foundation() +
theme(
panel.grid.major.x = ifelse(grid.vertical == T, element_line(), element_blank())
))}
produces..
Error in (function (el, elname) :
Element panel.grid.major.x must be a element_line object.
Is there a way to make this work?
It seems that the error is produced by an unpleasant peculiarity of ifelse. I tried the workaround from the accepted answer there, but that did not help. So I guess the simplest way would be to switch to the regular if, though the code doesn't seem to be particularly neat.
style.if = function (grid.vertical = T) {
t <- theme()
if (grid.vertical)
t <- t + theme(panel.grid.major.x = element_line(colour = 'red'))
else t <- t + theme(panel.grid.major.x = element_blank())
t
}
ggplot(mtcars, aes(x=wt, y=mpg)) + geom_line() + style.if()
ggplot(mtcars, aes(x=wt, y=mpg)) + geom_line() + style.if(F)
This has to do with how the ggplot code is checking for types:
...
else if (!inherits(el, eldef$class) && !inherits(el, "element_blank")) {
stop("Element ", elname, " must be a ", eldef$class,
" object.")
}
Since we're using the ifelse function, I think this dynamic type checking voodoo will look at ifelse as being the "element" here, so the conditions are never met since it doesn't inherit from element_blank. To solve this, just use regular if/else expression instead of ifelse:
style = function (grid.vertical = T) {
(theme_foundation() +
theme(
panel.grid.major.x = if(grid.vertical == T) element_line() else element_blank()
))}
I had the exact same problem and this solution worked for me.
How does one properly display special characters ("(", "ë", periods as commas, etc.) used in column names within a ggplot graphic?
My csv's column line looks like this:
r, á/b, ő/é, w/s (0.3), w/s (0.2), bins
And I'd like, for instance, the 4th variable to be displayed (in the ggplot legend), as "w/s (0.3)".
Here's my code:
require(reshape2)
library(ggplot2)
library(RColorBrewer)
fileName = paste("/2.csv", sep = "") # test file available here: https://www.dropbox.com/s/f2egxbuwwbba2q9/2.csv?dl=0
mydata = read.csv(fileName,sep=",", header=TRUE)
dataM = melt(mydata,c("bins"))
ggplot(data=dataM, aes(x= bins, y=value, colour=variable, size = variable)) +
geom_line(alpha = .9) +
scale_colour_manual(breaks=c("r","á/b","ő/é","w/s (0.3)","w/s (0.2)"), values=c("green","orange","blue","pink","yellow")) +
#scale_colour_brewer(type = "qual", palette = 7) +
scale_size_manual(breaks=c("r","á/b","ő/é","w/s (0.3)","w/s (0.2)"), values=c(1,0.5,0.5,0.5,0.5)) +
theme_bw() +
theme(plot.background = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(),
legend.key = element_blank(), legend.title = element_blank()) +
scale_y_continuous("D", expand=c(0,0)) +
scale_x_continuous("E", expand=c(0,0)) +
theme(legend.position="bottom")
Which produces this:
We can see how the legend wrongly display special characters. Any quick way (or not-so-quick way) to fix this?
(I have other questions about this graphics, but I believe it is preferred to ask a new complete question, which I'll do right now)
I think all you need to do is include check.names=FALSE in your read.csv() call; the special characters in your header are getting converted when the data is read in (see ?make.names for more information).
I was initially a little confused by your question because I assumed the problem was with accented characters such as ë, whereas in fact letters are not getting messed up -- it's only non-alphanumeric characters that are replaced by dots (also, strings starting with a numeric value would have "X" prepended).