Zoom in and out while using Locator() in R - r

I have an XY scatter plot of many points which define filament like structures (imagine looking at a pile of sticks laying on the ground, that's what these plots look like). I am using Locator to identify a start and end of each filament. The end result I get is a table of line segments defined by two points in XY.
A simplified base version of my code runs like this:
n=1
NumberOfFilaments=5
Xdata=rnorm(1000,mean=500,sd=100)
Ydata=rnorm(1000,mean=500,sd=100)
clicks.table=c()
while (n<=NumberOfFilaments) {
plot (Xdata,Ydata)
clicks = locator(2)
A = c(clicks$x[1],clicks$y[1])
B = c(clicks$x[2],clicks$y[2])
clickpoints = c(A,B)
clicks.table = rbind(clicks.table,clickpoints)
n=n+1
}
Some of my data sets have gotten quite large in regard to the total width of the data in X & Y in comparison to the length of the filaments I am trying to click on. This makes it hard for me to accurately click on the start and end of the filaments. What I would like to be able to do is zoom in on the plot to view an individual filament, click two points then zoom out to view the whole pile again. I typically use R studio if that matters. Thank you in advance.

Related

How to draw scrolling graphics in R, like financial time series

I would like to draw financial time series in R, that are continuously updated all along the day. Sometimes I can have several updates per second and I want to draw the time series as it evolves.
Moreover, I want to improve my graphics with extra information that I will plot too on the same graph (not necessarily a time series).
So I wonder if there is either:
a package in R to draw such series and have them scroll automatically as soon as I push new data
or a way to do bit blit in R and simply update my graph,
or a way to use packages like grid or anything else that would draw what is necessary (at least lines and points) and help scroll the data quickly to have a smooth rendering.
I would like something a bit more modern than a TCL/TK solution like explained here
We are doing this with shiny and a timer variable which refreshes the plot every n seconds.
R itself isn't really made for continuous updates. The (default) graphics device is static (so you can't easily 'append one point'), and there is only one event loop.
You can do it with external programs -- I have used both custom Qt applications I wrote for this as well as custom data handler in the (awesome, under-appreciated) kst real-time visualization program.
I'm not on financial data, but if the data file is itself updated along the day, the simplest solution would be something like:
k <- 0
while ( k<=3600 ) {
foo <- read.table("data.txt")
plot(foo[,1], foo[,2])
Sys.sleep(60) # seconds
k <- k+1
}
This would redraw the plot each 60 seconds. You can put a web adress for the data instead of "data.txt" also. To "scroll", you can play with the xlim argument to plot().

Can you create an invisible plot in R? How to switch from one plot to another?

Well, the question is as simple as this: can you create an invisible plot in R? Can you create a plot without displaying it until you decide to do so?
Suppose you have the following code:
x <- (0:360) / 180 * pi
y <- sin(x)
z <- cos(x)
plot(x, y)
dev.new()
plot(x, z)
The code above will immediately display the second plot and hide the first.
Suppose you want to create and build the second plot but not display it until you actually decide to do so: not before. In the meantime, while you build the second plot you want to keep displaying the first plot. Is there a way to do that?
Also, once you have two plots, how do you switch from one to the other, i.e. choose to display one or the other as needed?
Functions dev.set, dev.cur, dev.prev and dev.next are useful to make windows active or inactive; however I could not make them hide the second plot while displaying the first and then switch from displaying the first to displaying the second.
Note that I do not want to shut windows, just switch from one to the other as needed. Also, I do not need to create gif animations.

How to set logarithmic scale and axis limits in HistogramLUTItem in pyqtgraph

I'm using pyqtgraph for a live view of a camera acquisition program. Most of the times my images are composed of a lot of background noise and a signal of just a few pixels with higher intensity. For that reason, the part of the HistogramLUTItem that corresponds to the actual signal looks like a thin line and the noise is big next to it. Being able to plot the logarithm of the data would make the data to stand up more.
Is this possible?
I'm currently creating the histogram this way:
imagewidget = pg.GraphicsLayoutWidget()
self.p1 = imagewidget.addPlot()
self.img = pg.ImageItem()
self.p1.addItem(self.img)
self.p1.getViewBox().setAspectLocked(True)
self.hist = pg.HistogramLUTItem()
self.hist.setImageItem(self.img)
self.hist.autoHistogramRange = False
imagewidget.addItem(self.hist)
Doing self.hist.axis.setLogMode(True) didn't work as it affected the x-axis of the histogram instead of the y-axis.
And finally, I would also like to be able to limit the accesible range in the x-axis of the histogram. How can this be done?
Cheers!
Ok, I finally figured out. In case someone wonders, I solved it by adding these two lines:
self.hist.plot.setLogMode(False, True)
self.hist.vb.setLimits(yMin=0, yMax=16000)

Range and increment of data in Matlab

Lets consider I am given a plot and I do not have its x and y vectors but I would like to extract them from the plot in Matlab. Also I am interested to know the increment of data (step size) in both horizontal and vertical axis(x and y axis).
I was thinking of using :
h=gca % Get current axis
X=get(h,'xdata');
Y=get(h,'ydata');
stepsize=X(2)-X(1);
But these command produce an error message that :
xdata and ydata are not accessible property of axis. Any suggestion how to find the x and y vectors for any given curve.
If I understand correctly, these are the two things you want to know:
You have a figure containing a plot of some arbitrary 2d line, whose x_vec, y_vec are unknown to you and you want to extract them from the figure\axes.
You want to get the xtick and ytick positions used in the figure you have.
The reason your code does not work, is because you're trying to access a property of the axes, whereas what you want to access is the property of the line (i.e. the curve in the plot).
To solve your first problem, you can resort to the following methods:
Manual: using the edit plot figure tool you can get to the XData and YData properties of the line, in the following manner:
Programmatic: you need to find the handle (i.e. pointer) to the line, and then use your code on that handle (and not on gca):
%// If there's only one entity (child) in the axes:
hLine = get(gca,'Children');
%// If there's more than one child:
hChildren = findobj(gca,'Type','line');
hLine = hChildren(1); %// Or any other logic you need to pick the correct line
%// Then comes your code:
xD = get(hLine,'XData'); yD = get(hLine,'YData');
For the second problem you can use gca to get XTick and YTick:
xT = get(gca,'XTick'); yT = get(gca,'YTick');
To get the step size I'd suggest simply using diff().
I'm not sure I quite understand your question. You mean get x and y data of a curve? If yes, then maybe it'll help looking into 'ginput'.
For example, picking 10 points from a figure window you can use the following command
[x,y] = ginput(10)

Is there a way to identify the same point twice in a plot?

I'm creating a plot of data that should be linear and using identify(x, y) to remove equipment artifacts. However I want to add the ability to click the point again as a sort of 'undo' and then later in my code remove any duplicated points. When you attempt to click a point a second time you receive this warning:
'warning: nearest point already identified'
which is expected based on the identify() help page.
Is there any work around for this problem using base graphics or would I have to switch to a more interactive graphics package? And if so any suggestions?
example <- data.table(x = c(1:25), y = c(5+1:14*2, 60, 5+16:25*2))
plot(y~x, data=example)
example_artifact_rm <- example[!identify(example[,x], example[,y])] <- click the artifact and identify it
How can I 'unidentify' if I accidentally click the pair (2,9)?

Resources