how to use an atomic vector as a string for a graph title in R - string

I'm trying to plot a graph from a matrix of z-scores in R, i would like to build a function to iterate through each column using the column header as part of the title and saving each graph as a png.I think I know how to do the iteration and saving graphs as pngs but I am getting stuck with using the vector as a string. I tried to upload the matrix with no column headers and then store matrix[1,] as a variable 'headers' to use. Then I tried to plot:
plot(1:30, rnorm(30), ylim=c(-10,10), yaxs="i", xlab = "Region", ylab = "Z-Score",main = "CNV plot of " + headers[i], type = "n")
I get:
Warning message:
In Ops.factor(left, right) : + not meaningful for factors
I try without the '+' and it says:
Error: unexpected symbol in ...
So then I looked around and found 'paste(headers[i],collapse=" ") which I though I could substitute in but it just puts the number '28' as the title.
I've tried what I thought was another potential solution:
plot(1:30, rnorm(30), ylim=c(-10,10), yaxs="i", xlab = "Region", ylab = "Z-Score",main = "Z-scores of " $headers[i], type = "n")
and I get:
Error in "Z-scores of "$headers :
$ operator is invalid for atomic vectors
I'm new to R and this seems like something that would be so simple if I happened to stumble across the right guide/tutorial after hours of google searching but I really don't have that kind of time on my hands. Any suggestions, pointers or solutions would be great??

If you want to insert values from variables into strings for a plot title, bquote is the way to go:
headers <- c(28, 14, 7) # an examle
i <- 1
plot(1:30, rnorm(30), ylim=c(-10,10), yaxs="i",
xlab = "Region", ylab = "Z-Score", type = "n",
main = bquote("CNV plot of" ~ .(headers[i])) )
Have a look at the help page of ?bquote for further information.

paste("CNV plot of", headers[i]), should work. You only need collapse if you are pasting vectors of length greater than one (headers[i] should be one length, even if header is not). R doesn't have any concatenation operators, unlike PHP, JS, etc (so +, &, . will not work, you have to use paste).
Note that your paste was paste(headers[i],collapse=" "), and if that just plotted 28, it suggests your headers vector doesn't contain what you think it does (if you didn't want 28 to be displayed, that is.
Try just looping through your vector and printing the paste command to screen to see what it displays (and also, just print the vector).

Related

Visual Python using a for loop to track a changing axis?

I have a giant array that I am importing from a text file holding 200,000 values which all describe how an arrow should be traversing along the x axis. Mx is the name of the array that I have imported from this text file. I am using visual python to try and simulate this movement across the axes.
arrow = arrow(length = 1.0,pos = (0,0,0),axis=(0,0,0),color=color.blue)
for i in range(len(Mx)):
rate(60)
arrow.axis.x = Mx[i]
When I run my code the arrow remains stationary, and "QObject::killTimers: timers cannot be stopped from another thread" this error message pops up. I am not sure why. Any advice would be really helpful.
What I found is that this fixed it for some reason.
arrow = arrow(length = 1.0,pos = (0,0,0),axis=(0,0,0),color=color.blue)
for i in range(len(Mx)):
rate(60)
x = Mx[i]
arrow.axis.x = x
Not 100 percent sure why, but I am guessing it has something to do with how python handles the array that I imported from the text file.

Formatted String from List Psychopy

My task is a variation of a multiple object tracking task. There are 7 circles on the screen. It randomly selects 3 circles to change the color (red, green, blue) briefly to indicate to the participant to track these circles. After the color change, all the circles will change to the same color and the circles will move for a period of time. When the circles stop moving, a response prompt will appear, where the participant is to select one of the three colored circles ('select the red/green/blue circle'). I am having difficulty inserting which color circle to select into the formatted string. I keep getting the error message: unsupported operand type(s) for %: 'TextStim' and 'list'
I'm not sure if I need to or how to convert these lists, so any help would be much appreciated!
n_targets = 7 #seven locations
circles = [] #setting up the circle stimuli
for i in range(n_targets):
tmp = visual.Circle(win,radius = 27,units = 'pix',edges = 32,fillColor='white',lineColor = 'black',lineWidth = 1, pos=(posx[i],posy[i]))
circles.append(tmp)
cols = ['blue','red','green'] #3 colors the circles will change to
targets = random.sample(circles,3) #randomly select 3 of the 7 circles
TrialTarget = random.sample(targets, 1) #select 1 of the 3 circles to be the target for the trial
#code for movement would go here (skipping since it is not relevant)
#at end of trial, response prompt appears and ask user to select target and is where error occurs
ResponsePrompt = visual.TextStim(win, text = "Select the %s circle") %TrialTarget
In this line, you are trying to create a formatted string from a TextStim object and a Circle stimulus object rather than a string object and another string object:
ResponsePrompt = visual.TextStim(win, text = "Select the %s circle") %TrialTarget
i.e. ResponsePrompt is clearly a visual.TextStim, as you are creating it as one, and I think TrialTarget is a visual.Circle stimulus, as you randomly sample it from a list of Circles.
I'm guessing that you actually want to incorporate the colour label into the prompt text. So to fix both problems (the type incompatibility and the formatting syntax), you need to actually get one of the elements of cols, called say trialColour, and use something like this:
ResponsePrompt = visual.TextStim(win, text = "Select the %s circle" % trialColour)
i.e. here trialColour is actually a string, and the formatting operation is brought inside the brackets so it applies directly to the text string "Select the %s circle"
That should hopefully fix your immediate problem. You might also want to investigate using random.shuffle() to shuffle lists in place instead of random.sample().

Matlab - Using symbols in gscatter

Ok, so I'm trying to use gscatter to plot 8 different points in a figure. These 8 points are all different and thus I want to give them different symbols. I know that gscatter will automatically assign them different colors, but I also want to be able to use the figure in black and white. I have written the following code:
lincol = {'k';'k';'k';'k';'k';'k';'k';'k'};
linsym = {'+';'o';'*';'.';'x';'s';'d';'^'};
limits = [-1 1 -1 1];
close all
for i = 1:3;
figure(i); hold on
gscatter(RfootXdistpertRel(:,i),RfootYdistpertRel(:,i),lincol,linsym);
legend('Pert1', 'Pert2', 'Pert3', 'Pert4', 'Pert5', 'Pert6', 'Pert7', 'Pert8')
hline(0);
vline(0);
axis(limits);
end
According to the matlab syntax, I should be able to specify color and marker symbol in this way (gscatter(x,y,col,sym)). The variables used are 8 by 1 vectors, just as the lincol and linsym. However, it gives me an error:
Error using plot
Color value must be a 3 or 4 element vector
Can anyone help? It's just such a silly problem to have.
Luc
It seems that you have some errors in your code. The syntax for gscatter should include at least 3 parameters : x, y and group. It seems that group is missing.
Furthermore the definition of color and sym may be wrong. Try col = 'kkkkkkkk'; instead of lincol = {'k';'k';'k';'k';'k';'k';'k';'k'};.
I hope this helps.
Regards.
Jonay

two textplots in one plot

I have been trying to work with textplot in R and am unsure if my question is possible or not, I know that par() can't be used to place two textplots in one plot. I have been using a page and this code to try and figure things out.
My question is: Is it possible to have two textplots within the same plot?
For example, in the par(mfrow=c(1,1)) scenario below, plot 1 is a texplot of species length. Say I wanted to replicate that textplot twice in that plot. Is that possible?
based on this site:
http://svitsrv25.epfl.ch/R-doc/library/gplots/html/textplot.html
textplot(version)
data(iris)
par(mfrow=c(1,1))
info <- sapply( split(iris$Sepal.Length, iris$Species),
function(x) round(c(Mean=mean(x), SD=sd(x), N=gdata::nobs(x)),2) )
textplot( info, valign="top" )
title("Sepal Length by Species")
What I want to do is put a second textplot within that plot, underneath the original. For arguments sake, replicating that textplot twice in the plot.
Is this possible?
Thanks!
Maybe you've figured it out in the last four months but I thought I'd chip in an answer anyway.
The code provided is most of the way towards doing what you require already, you just have to provide some additional inputs to title() and/or par(). Namely specify that the title is to be above both of the plots by using title("your title", outer = TRUE) and you can further adjust the position of the title with an option in par(), use par(mfrow = c(2,1), oma = c(0,0,"top",0)). Hopefully this answers your question.
require('gplots')
data(iris)
info <- sapply(split(iris$Sepal.Length, iris$Species),
function(x) round(c(Mean = mean(x), SD = sd(x), N = gdata::nobs(x)),2))
## Replace top with a numerical value to control the position of the title with respect to the
## top of the page.
par(mfrow = c(2,1), oma = c(0,0, top ,0))
textplot(info, valign = "top")
textplot(info, valign = "top")
title("Sepal Length by Species", outer = TRUE)

Bumpy jigsaw type data into curve data

I have a problem I solved in Excel but I am completely stuck in Matlab.
A weight measuring how much liquid I pump is refilled when its almost empty. Here is a picture
Now I want to see it in one motion, not like a jigsaw. Here is my solution, doing it manually in Excel:
Now to Matlab where this should be done automatically: I know how to index the row before and after I have the bumps, but I'm kind of stuck now. I do d=diff(x) ok and now I can replace the high peaks when the bumps occur (i=d(:,1)>0) with 0 so it never happened. And how do I translate it back? Somehow "undiff(x)"? im completely lost.
Here's an extract of my x:
2533,30
3540,00
3484,90
3430,00
3375,00
3320,20
3265,60
3210,60
3155,80
3101,20
3046,50
2991,70
2937,00
2882,50
2828,10
2773,80
2719,30
2664,90
2610,50
2556,10
2501,60
3508,00
3454,00
3399,70
3352,10
Like this?
temp = [0; diff(x)];
temp(temp < 0) = 0;
y = x - cumsum(temp);
y(temp > 0) = interp1(y, find(temp > 0) + 0.5);
plot(y);
hen using the default plot() function, matlab will automatically draw a line plot and connect each point in the data you are plotting.
Instead it seems like you just need to plot the points individually and unconnected. So if you are currently doing something like plot(x) or area(x) instead try plot(x,'o'). This will cause Matlab to plot the points individually without connecting them as lines.
If you'd like to change the marker type used to plot each point, use doc linespec to get more info.

Resources