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().
Related
I am trying to use the default plot() function in R to try and plot a shapefile that is about 100MB, using RStudio. When I try and plot the shapefile, the command doesn't finish executing for around 5 minutes, and when it finally does, the plotting window remains blank. When I execute the same process exactly in VS Code, the plot appears almost instantly, as expected.
I have tried uninstalling and reinstalling RStudio with no success.
I can't speak for what VStudio does, but I can guarantee that plotting 100MB worth of data points is useless (unless the final plot is going to be maybe 6 by 10 meters in size).
First thing: can you load the source file into R at all? One would hope so since that's not a grossly huge data blob. Then use your choice of reduction algorithms to get a reasonable number of points to plot, e.g. 800 by 1600, which is all a monitor can display anyway.
Next try plotting a small subset to verify the data are in a valid form, etc.
Then consider reducing the data by collapsing maybe each 10x10 region to a single average value, or by using ggplot2:geom_hex .
I plot a lot of graphs in gnuplot. These graphs are based onn sensor readings from around the solar power system.
Each graph has needed to be updated by typing something like
load "solar
where solar is a gnuplot program that performs the plot showing the condition of the 24 V (500Ah) battery bank and leaves it on the screen so I can do a regional screen capture for storage.
In this particular case, the numbers come in at 2-minute intervals. Unless the inverter is turned on, in which case they come in at 20 second intervals. So I end up typing that command a lot just to see how clean the signal is.
So the question came up as to whether I need to continue to tell it to load the program every time I want to see updates.
How can I actually make it automatically live?
Turns out it is as simple as can be to have it run live.
This article: Running Gnuplot as a live graph, with automatic updates
explains the process nicely.
Turns out that all you need to do is add two lines of code after the plot command. In my case, I want it to update the graph every 15 seconds, so the last two lines of the program are simply
pause 15
reread
Here is an excerpt from the article:
Gnuplot has some useful commands we can use:
pause
reread
These are fairly self-explanatory, so let’s make a Gnuplot file, liveplot.gnu, that refreshes itself once every second.
set xrange [0:20]
set yrange [0:400]
plot "plot.dat" using 1:2 with lines
pause 1
reread
We set the bounds of our graph, then plot the data from the file. using 1:2 means plot columns 1 and 2 as x and y, respectively. with lines means that the points are joined together rather than plotted separately. We pause for 1 second and then reread, meaning that the command file is re-executed.
It turned out to be so simple that I am going to add those two lines to all my graphs that I monitor on the xterminals of the individual Rpi3s that monitor the sensors.
Collected together on the big screen it gives me a great overview of the entire system, including temperatures and voltages and such.
The best part is that there is no need to specify the X range to be fixed. It is much better to let it recalculate every time it rereads.
Results: A true live graph, monitoring conditions of the sensors from which it is receiving near-real-time data.
(You can see how hot the panels get even on a relatively cool day, and how the MPPT charge controller works to maintain the voltage)
https://www.SDsolarBlog.com/montage
I try to receive the data from a sensor from time to time and plot it in real time. That means the length of the dataset is not know before hand. And need to adjust the range of the graph dynamically.
I tried the following
plot(1,10, xlim=range(0,10), ylim=range(0,10), type='n')
points(1,data[1])
points(2,data[2])
But once the number of dots is beyond the range of x axis (10 in this case), the data points are out of the range. How to adjust the range accordingly?
Just issue a new plot command with an expanded range. On modern computers the time taken to recreate the plot is small and you generally will not see a delay. Any other approach will essentially do the same thing, clear the current plot and create a new plot.
The ggplot2 and lattice packages have ways of constructing a plot and updating the plot, but when the updated plot is shown it is redrawn from scratch.
There is a zoomplot function in the TeachingDemos package which will allow you to change the range of a plot, but it also will just redraw the plot from scratch (and due to changes in R 3.0.0 it is not currently working, so if you wanted to use it you would need to go back to R 2.15 or before, or wait for it to be fixed).
You can't adjust the range dynamically (sometimes Excel is better). However, you can keep track of what you've plotted, and redo the plot when you've reached the limit. You could also just make a new plot every time you get more data, which would be a way of faking a dynamic update.
I have certain x and y coordinates for the position of an animal for a certain time t-max. I am using the code in R:
for (t in 1:tmax) {
plot(x[1:t],y[1:t]);
Sys.sleep(0.1);
}
to see how the animal is moving with time. So this shows me the path from each value of x to the subsequent value, till tmax. So now i have to present my findings in a Powerpoint presentation. so i was wondering if there is a method to insert this graph in a slide so that when i click a button, the graph is plotted and everybody can understand how the animal is moving.
Have a look on the Animation-Package on Cran:
http://cran.r-project.org/web/packages/animation/index.html
The animations package is cool, but i found it hard to learn. Instead of sleeping after each point is plotted, you could save the graph, and then use a video editor to merge the graphs into a movie clip. Windows movie maker will do this for you.
I'm not a big fan of animation, and in this case it doesn't seem useful. Why not just plot the graph, or if the path is seriously tangled, plot with a rainbow colormap applied to the line so you can easily follow from start to finish? See plotrix::color.scale.lines
If I create a multi-plot window with par(mfrow=...), is it possible to send data to a specific plot (i.e. "the one in the lower left corner") or is the plotting always necessarily sequential? Is there a package for R that does something like this?
For those that are interested, this problem arises out of the fact that R is a single-threaded application and is not ideal for real-time visualization. I have multiple real-time data streams coming into R from an outside source that produces the data asynchronously (and therefore the data streams don't always come in the same order). This results in R flipping around the order of the data visualization plots every time it updates.
You could use split.screen():
par(bg = "white") # erase.screen() will appear not to work
# if the background color is transparent
# (as it is by default on most devices).
split.screen(c(2,1)) # split display into two screens
split.screen(c(1,3), screen = 2) # now split the bottom half into 3
screen(1) # prepare screen 1 for output
plot(10:1)
screen(4) # prepare screen 4 for output
plot(10:1)
Have a look at help(layout). This allows you to specify the what, where and in which sizes.
Once plotted, I don't think you re-plot just partially. But you you can use dev.set() et al to switch between different 'plot devices' (ie windows); see help(dev.list).
Note that the suggested answer here is to use split.screen(). It may work, but according to the split.screen help file: "The recommended way to use these functions is to completely draw a plot and all additions (i.e. points and lines) to the base plot, prior to selecting and plotting on another screen. The behavior associated with returning to a screen to add to an existing plot is unpredictable and may result in problems that are not readily visible."
In an answer to my question, there is a more useful solution, using the par(mfg) option:
Change plot panel in multipanel plot in R
Another option is that of implementing a little GUI e.g. with RGtk2 or RTclTk.
I generally do this for graphs that I want to change in realtime and it works great.
For instance, with RGtk2 and cairoDevice you could just do something like (I assume you have a Glade interface)
# Helper function to get a widget from the Glade interface
getWidget <- function(name)
{
return (interface$getWidget(name))
}
interface <- gladeXMLNew("interface.glade", root="mainWindow")
# Our cairo devices (to draw graphics).
# plot1, plot2, and plot3 are GtkDrawingArea widgets
asCairoDevice(getWidget("plot1"))
# dev.cur() will give the device number of the last device we created
# You'll use this to switch device when you draw in different plots
# Storing the device number is important because you may have other
# devices open from other unrelated plots
# (so never assume they'll just start from 1 and be sequential!!!)
plot1.dev <- as.integer(dev.cur())
asCairoDevice(getWidget("plot2"))
plot2.dev <- as.integer(dev.cur())
asCairoDevice(getWidget("plot3"))
plot3.dev <- as.integer(dev.cur())
# To draw in a specific plot you just do
dev.set(plot2.dev)
plot(....)
This has many other advantages, like that of being able to positions the graphs easily where you want (using Glade Interface Designer) and having the possibility of user interaction through specific buttons (e.g. you may have a "pause acquisition" button).