I need to label my y axis so that it displays first the word "Power" followed by an expression in square brackets: [micro Volt squared].
I can produce single parts of the overall label that I want, but I run into problems when I want to combine them:
x <- 1:10; y <- 10:1; z <- data.frame(x,y)
g <- ggplot(z, aes(x,y) + geom_bar(stat='identity')
g + ylab('Power') # No problem
g + ylab(paste('Power [', ']')) #No problem
g + ylab(expression(mu)) # No problem
g + ylab(expression(V^2)) # No problem
However, this seems not to be possible:
g + ylab(paste('Power [', expression(mu), expression(V^2), ']'))
The output does not evalute the expressions (mu and V^2):
Where am I going wrong? Is the paste() command the wrong approach in general? I have also had a look at unicode characters (Unicode Characters in ggplot2 PDF Output) ... but that would still leave me with the question how I adequately combine all the single terms.
Your help is much appreciated!
You need to put everything inside the expression.
You can use an asterisk for separation, the tilde is for space. So this should be right.
g + ylab(expression("Power"~"["*mu*V^2*"]"))
A single expression seems to do the trick:
g + ylab(expression(paste("Power [",mu, V^2,"]")))
Related
I am working on a plot in which I have scaled the horizontal axis by a factor of ten thousand. I've been trying to include that in my axis label, but have consistently failed. However, what I've found is that this works:
g <- g + xlab(expression(paste("Word Count ", (x %.% 10^4))))
but this does not:
g <- g + xlab(expression(paste("Word Count ", (%.% 10^4))))
The latter throws the error "Unexpected special in...".
Were I to be writing the label I wanted in LaTeX, it would be: $\text{Word Count } \left( \cdot 10^4 \right)$.
How do I get the axis label I'm after without the extra character?
For whatever reason, expression needs something on the left-hand side. However, that something can be NULL, so this works:
g <- g + xlab(expression(paste("Word Count ", (NULL %.% 10^4))))
I have searched here for a while and my question was partially answered by previous questions/answers. I am learning R, coming from Matlab. As the title says, I have a question about plot annotations. In Matlab it was fairly straightforward to have plot annotations that contained all sorts of data formats, and I am looking for something similar in R. I have already discovered paste and managed to put text and numbers into one annotation and I also figured out (to a degree...) what parse does, for example when displaying an r squared. My question is, how do I combine the two annotations in the code snippet into one annotation without R yelling at me? My solution with two annotations works for what I need, but I simply would like to know how to do it...
a <- 30 # some coefficients
b <- 70
r2 <- 0.87
anno1 <- paste("y = ",b,"ln(x) + ",a) # first annotation with a random equation
anno2 <- paste("r^2 == ", r2) # second annotation with a random r squared
Pdata <- data.frame("X" = 1:10, "Y" = 1:10) # some data
ggplot(Pdata,aes(x=Pdata$X,y=Pdata$Y)) +
geom_point() +
annotate("text", x=2, y=8, label=anno1, parse=FALSE) +
annotate("text", x=2, y=7, label=anno2, parse=TRUE)
Thanks y'all!
It took a while for me to figure this out (for my own projects), but here's a solution:
anno3 <- paste("'y ='~",b,"~'ln(x) +'~",a,"~r^2==~", r2)
Add it to your plot using + annotate("text", x=2, y=6, label=anno3, parse=TRUE)
The single quote identifies text to not evaluate. Combined, the pasted result should be written like an expression.
Here is one way to do the requested operation by using bquote
ggplot() +
geom_point(aes(x = 1:4, y = 1:4)) +
annotate("text", x=2, y=3,
label = deparse(bquote(~y ==~ .(b) ~ln(x)~ + .(a) ~r^2 ==~ .(r2))),
parse = T)
bquote quotes its argument except the terms wrapped in .() which are evaluated
annotate does not support expressions, one trick to get it to work is to deparse it and then parse it again
I am trying to place one word over another for a title. I mean literally over, not just a 'divides by' sign one value over another (or word) to save space. It is supposed to mean divides by and there needs to be a line.
I cannot find how to do this, can you help?
Thanks,
Chris
You can create fractions in a title with frac():
p <- ggplot(mtcars, aes(x = mpg, y = disp)) + geom_point()
p + ggtitle(expression(paste("This is a fraction: ", frac(foo, bar))))
Note that the whole title must be put inside expression(). Alternatively, you can also use over() to do the same. The following example also shows that you can create other mathematical expressions in a similar fashion:
p + ggtitle(expression(paste("This is a fraction: ", over(3 * alpha, sum(b[i], i==1, N)))))
For more information, read ?plotmath.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Problem
I have 50 .csv files with this structure:
value1,value2,...
One single long line with each value separated by a comma.
Specifically they are floating point numbers and each csv has a different number of values.
0.0023593,0.0062565,0.00723753,0.0023353,0.0052353,0.0024353,...
I have to plot each data file in the same graph, to find the trend of this values and possibly with an average plot.
How can I do this in a simple manner? Matlab is preferred but R is ok
Update
I know I can do something like [in Matlab]:
>> arr1 = csvread('file1.csv');
>> plot(arr1)
and
>> arr2 = csvread('file2.csv');
>> plot(arr2)
...but I'm looking for a procedural way.
Update2
Thanks for the answers, I've done a simple hack and I end up with the correct solution, but it is a hack. I've just used python to replicate the commands and then I runned all them...
#Crowley your solution could be right but unfortunately there are some syntax problems.
#njc thanks for your effort! but this is not what I needed, maybe my result can help you to develop R code, then I will surely promote your answer as the correct one.
Here the result:
Made with this "stupid" script
I'm afraid I don't know any MATLAB, but one way to do this in R is to use the ggplot2 package. It works by adding different layers to the plot, which makes it a convenient way to use different data frames.
First I generated some example data to use.
a <- data.frame(runif(100))
b <- data.frame(runif(150))
c <- data.frame(runif(125))
names(a) <- 'y'
names(b) <- 'y'
names(c) <- 'y'
These are just data frames of random variables that are different lengths. Because all your data seem to be one dimensional, I made a box plot.
Then I create a ggplot using each data frame separately.
p <- ggplot()
p <- p + geom_boxplot(data=a, aes(y=y, x=1, color='a'))
p <- p + geom_boxplot(data=b, aes(y=y, x=2, color='b'))
p <- p + geom_boxplot(data=c, aes(y=y, x=3, color='c'))
p # to show the plot
Each time I use geom_boxplot() I'm adding another layer to the plot. You can also do this in one line.
p <- ggplot() + geom_boxplot(data=a, aes(y=y, x=1, color='a')) + geom_boxplot(data=b, aes(y=y, x=2, color='b')) + geom_boxplot(data=c, aes(y=y, x=3, color='c'))
p # to show the plot
Now that I'm reading your post again, it occurs to me that you might mean that you want to point these as scatter plots, with the position of the number in the file as the x value. That's easy to do with ggplot, though in my example you won't see any trend because my values are all random.
q <- ggplot()
q <- q + geom_point(data=a, aes(y=y, x=1:dim(a)[1], color='a'))
q <- q + geom_point(data=b, aes(y=y, x=1:dim(b)[1], color='b'))
q <- q + geom_point(data=c, aes(y=y, x=1:dim(c)[1], color='c'))
q
Or
q <- ggplot() + geom_point(data=a, aes(y=y, x=1:dim(a)[1], color='a')) + geom_point(data=b, aes(y=y, x=1:dim(b)[1], color='b')) + geom_point(data=c, aes(y=y, x=1:dim(c)[1], color='c'))
q
I hope this helps! Let me know if you have any questions about ggplot; I'll do my best though I'm certainly not an expert.
Note: I changed the column names of a, b, and c to 'y' before making the plots, but I forgot to update their names when making the data.
Is the only difference between this and what you want the smoothed curve instead of the points? If so, that's an easy fix.
First I changed the data so that it would have a trend.
a <- data.frame(runif(100)-(1:100)/300)
b <- data.frame(runif(150)-(1:150)/300)
c <- data.frame(runif(125)-(1:125)/300)
names(a) <- 'y'
names(b) <- 'y'
names(c) <- 'y'
Then I simply replaced geom_point with geom_smooth.
r <- ggplot()
r <- r + geom_smooth(data=a, aes(y=y, x=1:dim(a)[1], color='a'), se=FALSE)
r <- r + geom_smooth(data=b, aes(y=y, x=1:dim(b)[1], color='b'), se=FALSE)
r <- r + geom_smooth(data=c, aes(y=y, x=1:dim(c)[1], color='c'), se=FALSE)
r
The se=FALSE stops it from displaying the standard error as a gray band in the background. If the standard error is helpful to you, you can just omit it.
Say we have data in YourFolder='whatever\address\' folder, then if we want double array:
Files=dir(['YourFolder' .*']); % look for csv. files in the folder
[M,~]=size(Files); % count them
AllData=zeros(M,0);
for ii=1:M
Temp=importdata([YourFolder,Files(ii).name '.csv'],','); % Read csv file into a structure
Temp=Temp.data; & Use only the data part
if size(Temp,2>size(AllData,2) %compare 2. dimensions of AllData and Temp
% if Temp is wider, then append NaN values to AllData to match widths
n=size(Temp,2)-size(AllData,2);
Refill=nan(M,n);
AllData=[AllData,Refill];
elseif size(Temp,2<size(AllData,2)
% If AllData is wider then append NaN values to Temp to match widths
n=size(AllData,2)-size(Temp,2);
Refill=nan(1,n);
Temp=[Temp,Refill];
end
% append new line to AllData
AllData(ii,:)=Temp;
end
plot(AllData') % Alldata shall be transposed because plot uses columns as data sets by default.
If we want cell array to work with the code is simpler, since vectors doesn't need to match.
Files=dir(['YourFolder' .*']); % look for csv. files in the folder
[M,~]=size(Files); % count them
AllData=cell(M,1);
for ii=1:M
Temp=importdata([YourFolder,Files(ii).name '.csv'],','); % Read csv file into a structure
Temp=Temp.data; & Use only the data part
% append new line to AllData
AllData{ii}=Temp;
end
plot(AllData(:))
I have an R routine which creates a number of plots from a large set of data. Each plot is labeled with a titles describing the details of the set of points plotted. Unfortunately, I have not been able to use subscripts in the text if I am using paste to combine a complex label. The result is ugly. This is a simplified version of the code using data from R. The title shows the technique I am currently using, without subscripts. The attempt at an improved version is placed either on the x axis or on the plot.
library(ggplot2)
x1 = 1
x2 = 2
list <- c(1:4)
tle <- paste("VGM = ", as.character(list[1]),
"V, VDM = ", as.character(list[2]),
"V, VGF = ", as.character(list[3]),
"V, VDF = ", as.character(list[4]),
"V", sep="")
p <- ggplot(mtcars, aes(x=wt, y=mpg)) +
labs(title=tle) +
geom_point()
p
p + xlab(expression(V[DM])) #works fine
p + xlab(expression(paste(V[DM], "= 3"))) # works fine
# now we would like to use a variable to provide the number
p + xlab(expression(paste(V[DM], "=", x1))) # Just displays "x1", not value of x1
p + xlab(expression(paste(V[DM], "=",
as.character(x1)))) # NO
p + xlab(expression(paste(V[DM], "=",
as.character(as.number(x1))))) # NO
my.xlab1 <- bquote(V[DM] == .(x1))
p + xlab(my.xlab1) # We can see the success here
# A single variable at the end of the expression works
# What if you wanted to display two variables?
my.xlab2 <- bquote(V[GM] == .(x2))
my.xlab3 <- paste(my.xlab1, my.xlab2)
p + xlab(my.xlab3) # doesn't work
# Apparently the expressions cannot be pasted together. Try another approach.
# Place the two expressions separately on the plot. They no longer need to be
# pasted together. It would look better, anyway. Would it work?
p + annotate("text", x=4, y=30, label="Annotate_text", parse=TRUE)
# This is the idea
# p + annotate("text", x=4, y=30, label=bquote(V[DM] == .(x1)), parse=TRUE)
# This is a disaster
# RStudio stops the process with a question mark placed on the console. Appears that
# more input is being requested?
p + geom_text(x=4, y=30, label="Geom_text") # works
p + geom_text(x=4, y=30, label=my.xlab1) # does not accept variables.
I have included comments which describe the problems raised by each attempt. Ideally, the information should probably be placed as an annotation on the plot rather than as a title, but I cannot find a way to do this. Using a subscript turns a character into an expression, and it seems that there is a long list of functions which handle characters but not expressions.
If you want to "paste" two expressions together, you need to have some "operator" join them. There really isn't a paste method for expressions, but there are ways to put them together. First, obviously you could use one bquote() to put both variables together. Either
my.xlab3 <- bquote(V[DM] == .(x1)~ V[GM] == .(x2))
my.xlab3 <- bquote(list(V[DM] == .(x1), V[GM] == .(x2)))
would work. The first puts a space between them, the second puts a comma between them. But if you want to build them separately, you can combine them with another round of bquote. So the equivalent building method for the two above expressions is
my.xlab3 <- bquote(.(my.xlab1) ~ .(my.xlab2))
my.xlab3 <- bquote(list(.(my.xlab1), .(my.xlab2)))
All of those should work to set your xlab() value.
Now, if you also want to get annotate to work, you can "un-parse" your expression and then have R "re-parse" it for you and you should be all set. Observe
p + annotate("text", x=4, y=30, label=deparse(my.xlab3), parse=TRUE)