Ryan B
Ryan B

Reputation: 557

R Plot Flickers When Updating Lines

I found this question already, and it's helped me in the past: grid: Grid graphics flickering

However, I have that fix in place in my code, and I still see flickering when plotting multiple lines. The black line that is plotted using the plot command looks fine, but the red line flickers while the data is streaming in from the sensor.

enter image description here

(I'll add axis titles later)

Here's the code in question (I tried stacking the plots and that didn't help):

dev.hold

plot(dataX, dataY, type="l", lwd=2, ylim = yLimits)
lines(dataX, dataY2, type="l", lwd=2, col="red")  

#par(new=TRUE)    
#plot(dataX, dataY2, type="l", lwd=2, ylim = yLimits, col = "red")

dev.flush

The whole file isn't very large (about 120 lines) so I'll provide that for full context. The above lines are near the end.

# Clean up if last run crashed:
if(exists("com"))
{
    close(com)
}

#
# Reset environment
#

# Set working directory to dir of this source file.
setwd(getSrcDirectory(function(x) {x})) 

rm(list = ls())         # Remove environemnent variables
graphics.off()          # Close any open graphics

#
# Libraries
#
library(serial)

#
# Functions
#

MovingAverage <- function(data, window)
{
    return (filter(data, rep(1/window, window), sides = 1, circular = 1))
}

PulseFilter <- function(data)
{
    highPass <- 45
    lowPass1 <- 6
    lowPass2 <- 6

    data <- data - MovingAverage(data, highPass)
    data <- MovingAverage(data, lowPass1)
    data <- MovingAverage(data, lowPass2)
    return (data)
}

#
# Script
#

# configures settings for con.  Modify this file for local configuration.
source("com_config.R") 

open(con)

stopTime <- Sys.time() + 10
textRaw <- ""
while(Sys.time() < stopTime)
{
    textNew <- read.serialConnection(con)
    if(0 < nchar(textNew))
    {
        textRaw <- textNew
        textLines <- strsplit(textRaw, "\n")

        for(i in 1:length(textLines[[1]]))
        {
            textData <- strsplit(textLines[[1]][i], ", ")
            if(4 == length(textData[[1]]))
            {
                if(!exists("dataTime"))
                {
                    dataTime <- as.numeric(textData[[1]][1])/1000
                    dataIR <- as.numeric(textData[[1]][2])
                    dataRed <- as.numeric(textData[[1]][3])
                    dataState <- as.numeric(textData[[1]][4])
                }
                else
                {
                    dataTime <- c(dataTime, as.numeric(textData[[1]][1])/1000)
                    dataIR <- c(dataIR, as.numeric(textData[[1]][2]))
                    dataRed <- c(dataRed, as.numeric(textData[[1]][3]))
                    dataState <- c(dataState, as.numeric(textData[[1]][4]))
                }
            }
        }

        filterData <- 0
        adjustOffset <- 1

        if(exists("dataTime"))
        {
            dataX <- dataTime
            dataY <- dataIR
            dataY2 <- dataRed

            if(1 == filterData) # Enable filtering of displayed data
            {
                if(100 < length(dataX))
                {
                    dataY <- PulseFilter(dataY)
                    dataY2 <- PulseFilter(dataY2)
                }
            }

            xLimits <- c(0, 0)
            xLimits[2] <- max(dataX)
            xLimits[1] <- xLimits[2] - 10

            dataY <- dataY[xLimits[1] < dataX]
            dataY2 <- dataY2[xLimits[1] < dataX]
            dataX <- dataX[xLimits[1] < dataX]

            if(1 == adjustOffset)
            {
                dataY <- dataY - mean(dataY)
                dataY2 <- dataY2 - mean(dataY2)
            }

            yLimits <- c(0, 0)
            yLimits[2] <- max(c(dataY, dataY2))
            yLimits[1] <- min(c(dataY, dataY2))

            dev.hold
            plot(dataX, dataY, type="l", lwd=2, ylim = yLimits)
            lines(dataX, dataY2, type="l", lwd=2, col="red")  
            #par(new=TRUE)    
            #plot(dataX, dataY2, type="l", lwd=2, ylim = yLimits, col = "red")
            dev.flush
        }

        stopTime <- Sys.time() + 1
    }      
}

close(con)
rm(con) # remove con, so I can check if the script crashed.

Upvotes: 0

Views: 190

Answers (1)

Richard Telford
Richard Telford

Reputation: 9923

matplot should force the plot to be drawn all at once which should reduce flickering

matplot(dataX, cbind(dataY, dataY2), type="l", lwd=2, ylim = yLimits, col = c("black", "red"), lty = 1)

Upvotes: 1

Related Questions