The following sketch may give you some testing ability in case you have an Adafruit_ILI9341 display at hand:
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
const int Xoff = 32;
const int Yoff = 32;
const byte HalfMarkerLength = 4;
const byte TopOffset = 18;
const byte DotRadius = 2;
const unsigned long SampleInterval = 10000; // [msec]
const int maxData = 70; // No of Samples
int data[maxData];
int actData = 0;
int AverageLine = 0;
float StepPerDeviationMark; // 10 units from mark to mark
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
void setup() {
Serial.begin(9600);
Serial.println("Test");
tft.begin();
tft.setRotation(1);
CoordinateSystem();
CreateTestData();
}
void loop(void) {
static unsigned long lastMillis = 0;
if (millis()-lastMillis > SampleInterval){
lastMillis = millis();
data[actData] = random(-50,51);
PlotData(ILI9341_RED);
actData++;
if (actData >= maxData) RefreshField();
//if (actData >= maxData) RefreshPlots();
}
}
void CreateTestData(){
for (int i = 0;i < maxData-1;i++){
data[actData] = random(-50,51);
PlotData(ILI9341_RED);
actData++;
}
}
void RefreshField(){
Serial.println("Refresh");
int x = Xoff+ HalfMarkerLength;
int y = TopOffset;
tft.fillRect(x,y,tft.width()-x, tft.height()-y-Yoff-HalfMarkerLength, ILI9341_BLACK);
delay(300); // Give some time for erasing the data
// Reprint the average line
PlotFromTo(-HalfMarkerLength,AverageLine,tft.width(),AverageLine,ILI9341_YELLOW, false );
// Move all data one field to the "left"
for (int i = 1; i < maxData;i++) data[i-1] = data[i];
// Replot the "old" data
for (int i = 0; i < maxData-1;i++){
actData = i;
PlotData(ILI9341_RED);
}
actData = maxData-1;
}
void RefreshPlots(){
Serial.println("Refresh");
for (int i = 0; i < maxData;i++){
actData = i;
PlotData(ILI9341_BLACK);
}
for (int i = 1; i < maxData;i++) data[i-1] = data[i];
PlotFromTo(-HalfMarkerLength,AverageLine,tft.width(),AverageLine,ILI9341_YELLOW, false );
for (int i = 0; i < maxData-1;i++){
actData = i;
PlotData(ILI9341_RED);
}
actData = maxData-1;
}
void CoordinateSystem() {
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.println("Wind Graph");
// x axis
tft.drawLine(0,h-Yoff,w,h-Yoff,ILI9341_WHITE);
int StepPerMinute = (w - Xoff) / 6;
for (int i = 1; i < 6; i++) {
PlotFromTo(i*StepPerMinute,-HalfMarkerLength,i*StepPerMinute, HalfMarkerLength,ILI9341_WHITE, false );
tft.setCursor(i*StepPerMinute+Xoff-4, h-Yoff+HalfMarkerLength*2);
tft.print(i);
}
// y axis
tft.drawLine(Xoff,TopOffset,Xoff,w,ILI9341_WHITE);
StepPerDeviationMark = (h - Yoff) / 12;
tft.setTextSize(1);
int value = 50;
for (int i = 1; i < 12; i++) {
if (value == 0){
AverageLine = i*StepPerDeviationMark;
PlotFromTo(-HalfMarkerLength,AverageLine,w,AverageLine,ILI9341_YELLOW, false );
}
PlotFromTo(-HalfMarkerLength,i*StepPerDeviationMark,HalfMarkerLength,i*StepPerDeviationMark,ILI9341_WHITE, false );
tft.setCursor(4,i*StepPerDeviationMark);
tft.print(value);
value -= 10;
}
}
void PlotFromTo(int x1,int y1, int x2, int y2, uint16_t color, boolean MarkDot){
x1 = x1+Xoff;
y1 = tft.height()-(y1+Yoff);
x2 = x2+Xoff;
y2 = tft.height()-(y2+Yoff);
tft.drawLine(x1,y1,x2,y2,color);
if (MarkDot) {
tft.fillCircle(x1,y1, DotRadius, color);
tft.fillCircle(x2,y2, DotRadius, color);
}
}
void PlotData(uint16_t color){
//if (actData >= maxData) Refresh();
float StepPerData = (tft.width() -Xoff) / maxData;
int x = (actData+1) * StepPerData + HalfMarkerLength;
int y = (data[actData] * StepPerDeviationMark)/10 + AverageLine;
if (actData > 0) {
int x0 = (actData) * StepPerData + HalfMarkerLength;
int y0 = (data[actData-1]*StepPerDeviationMark)/10 + AverageLine;
PlotFromTo(x0,y0,x,y,color,true);
Serial.println(String(actData)+"->\t"+String(x)+"\t:\t"+String(data[actData]));
} else tft.fillCircle(x+Xoff,tft.height()-y-Yoff, DotRadius, color);
}
It has been written more or less "quick and dirty" so there will surely be some room for improvement.
However it shows the possibilities of
- Drawing the coordinate system including marks/tics and some numbers and text
- Erasing the plots by a black rectangle (see RefreshField() )
or erasing the plots by redrawing them with black color (see RefreshPlots() )
- Using an array to store the data and re-plot them after maximum data have been sampled
If more data have to be plotted RefreshField() becomes quicker than RefreshPlots().
Who wants may also check it out on Wokwi:
https://wokwi.com/projects/335069279045026388
P.S.: And this one "moves" the points from right to left stepwise ... 
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
const int Xoff = 32;
const int Yoff = 32;
const byte HalfMarkerLength = 4;
const byte TopOffset = 18;
const byte DotRadius = 2;
const unsigned long SampleInterval = 10000; // [msec]
const int maxData = 70; // No of Samples
int data[maxData];
int actData = 0;
int AverageLine = 0;
float StepPerDeviationMark; // 10 units from mark to mark
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
void setup() {
Serial.begin(9600);
Serial.println("Test");
tft.begin();
tft.setRotation(1);
CoordinateSystem();
CreateTestData();
}
void loop(void) {
static unsigned long lastMillis = 0;
if (millis()-lastMillis > SampleInterval){
lastMillis = millis();
data[actData] = random(-50,51);
PlotData(data,ILI9341_RED);
actData++;
//if (actData >= maxData) RefreshField();
//if (actData >= maxData) RefreshPlots();
if (actData >= maxData) RefreshPlotsStepWise();
}
}
void CreateTestData(){
for (int i = 0;i < maxData-1;i++){
data[actData] = random(-50,51);
PlotData(data,ILI9341_RED);
actData++;
}
}
void RefreshField(){
Serial.println("Refresh");
int x = Xoff+ HalfMarkerLength;
int y = TopOffset;
tft.fillRect(x,y,tft.width()-x, tft.height()-y-Yoff-HalfMarkerLength, ILI9341_BLACK);
delay(300); // Give some time for erasing the data
// Reprint the average line
PlotFromTo(-HalfMarkerLength,AverageLine,tft.width(),AverageLine,ILI9341_YELLOW, false );
// Move all data one field to the "left"
for (int i = 1; i < maxData;i++) data[i-1] = data[i];
// Replot the "old" data
for (int i = 0; i < maxData-1;i++){
actData = i;
PlotData(data,ILI9341_RED);
}
actData = maxData-1;
}
void RefreshPlots(){
Serial.println("Refresh");
for (int i = 0; i < maxData;i++){
actData = i;
PlotData(data,ILI9341_BLACK);
}
for (int i = 1; i < maxData;i++) data[i-1] = data[i];
PlotFromTo(-HalfMarkerLength,AverageLine,tft.width(),AverageLine,ILI9341_YELLOW, false );
for (int i = 0; i < maxData-1;i++){
actData = i;
PlotData(data,ILI9341_RED);
}
actData = maxData-1;
}
void RefreshPlotsStepWise(){
int olddata[maxData];
for (int i = 0; i < maxData;i++) olddata[i] = data[i];
for (int i = 1; i < maxData;i++) data[i-1] = data[i];
Serial.println("Refresh");
for (int i = 0; i < maxData;i++){
actData = i;
PlotData(olddata,ILI9341_BLACK);
if (actData < maxData-1) PlotData(data,ILI9341_RED);
}
PlotFromTo(-HalfMarkerLength,AverageLine,tft.width(),AverageLine,ILI9341_YELLOW, false );
actData = maxData-1;
}
void CoordinateSystem() {
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.println("Wind Graph");
// x axis
tft.drawLine(0,h-Yoff,w,h-Yoff,ILI9341_WHITE);
int StepPerMinute = (w - Xoff) / 6;
for (int i = 1; i < 6; i++) {
PlotFromTo(i*StepPerMinute,-HalfMarkerLength,i*StepPerMinute, HalfMarkerLength,ILI9341_WHITE, false );
tft.setCursor(i*StepPerMinute+Xoff-4, h-Yoff+HalfMarkerLength*2);
tft.print(i);
}
// y axis
tft.drawLine(Xoff,TopOffset,Xoff,w,ILI9341_WHITE);
StepPerDeviationMark = (h - Yoff) / 12;
tft.setTextSize(1);
int value = 50;
for (int i = 1; i < 12; i++) {
if (value == 0){
AverageLine = i*StepPerDeviationMark;
PlotFromTo(-HalfMarkerLength,AverageLine,w,AverageLine,ILI9341_YELLOW, false );
}
PlotFromTo(-HalfMarkerLength,i*StepPerDeviationMark,HalfMarkerLength,i*StepPerDeviationMark,ILI9341_WHITE, false );
tft.setCursor(4,i*StepPerDeviationMark);
tft.print(value);
value -= 10;
}
}
void PlotFromTo(int x1,int y1, int x2, int y2, uint16_t color, boolean MarkDot){
x1 = x1+Xoff;
y1 = tft.height()-(y1+Yoff);
x2 = x2+Xoff;
y2 = tft.height()-(y2+Yoff);
tft.drawLine(x1,y1,x2,y2,color);
if (MarkDot) {
tft.fillCircle(x1,y1, DotRadius, color);
tft.fillCircle(x2,y2, DotRadius, color);
}
}
void PlotData(int myData[], uint16_t color){
//if (actData >= maxData) Refresh();
float StepPerData = (tft.width() -Xoff) / maxData;
int x = (actData+1) * StepPerData + HalfMarkerLength;
int y = (myData[actData] * StepPerDeviationMark)/10 + AverageLine;
if (actData > 0) {
int x0 = (actData) * StepPerData + HalfMarkerLength;
int y0 = (myData[actData-1]*StepPerDeviationMark)/10 + AverageLine;
PlotFromTo(x0,y0,x,y,color,true);
Serial.println(String(actData)+"->\t"+String(x)+"\t:\t"+String(myData[actData]));
} else tft.fillCircle(x+Xoff,tft.height()-y-Yoff, DotRadius, color);
}
See https://wokwi.com/projects/335081139056149076