gpt4 book ai didi

ios - 使用 Core-Plot 的实时图上未说明的水平线

转载 作者:行者123 更新时间:2023-11-28 21:58:39 33 4
gpt4 key购买 nike

我正在尝试在同一张图上使用 4 个单独的图来绘制 4 channel 输入流的实时图。目前我正在从文本文件中获取这些数据,但最终会使用蓝牙获取这些数据。我的情节本身工作正常,但核心情节似乎在第一个数据集级别的绘图开始时为每个情节绘制了一条额外的水平线。我认为这与 core-plot 试图在开始显示之前绘制所有点有关。下图显示了这些线,而实际波形,方波,正在绘制中。

enter image description here

随着绘图的进行和 x 轴显示范围的变化,这些线会消失。就像在这里:

enter image description here

以下是我的代码的相关部分。它基于 Ray Wenderlich 的散点图教程和 Eric Skrooch 的实时绘图示例。 (我希望我拼对了这些名字!)。就我个人而言,我认为这是核心情节中的错误,而不是编码错误。非常感谢任何有关如何摆脱这些令人不安的线条的帮助!谢谢!

-(void)configurePlots {

//Get graph and plot space
CPTGraph *graph = self.hostView.hostedGraph;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;

//Create the four plots
CPTScatterPlot *channel1Plot = [[CPTScatterPlot alloc]init];
channel1Plot.dataSource = self;
channel1Plot.identifier = @"channel1";
[graph addPlot:channel1Plot toPlotSpace:plotSpace];

CPTScatterPlot *channel2Plot = [[CPTScatterPlot alloc]init];
channel2Plot.dataSource = self;
channel2Plot.identifier = @"channel2";
[graph addPlot:channel2Plot toPlotSpace:plotSpace];

CPTScatterPlot *channel3Plot = [[CPTScatterPlot alloc]init];
channel3Plot.dataSource = self;
channel3Plot.identifier = @"channel3";
[graph addPlot:channel3Plot toPlotSpace:plotSpace];

CPTScatterPlot *channel4Plot = [[CPTScatterPlot alloc]init];
channel4Plot.dataSource = self;
channel4Plot.identifier = @"channel4";
[graph addPlot:channel4Plot toPlotSpace:plotSpace];

//Set up plot space
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:channel1Plot, channel2Plot, channel3Plot, channel4Plot, nil]];
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
[xRange expandRangeByFactor:CPTDecimalFromCGFloat(1.1f)];
plotSpace.xRange = xRange;
CPTMutablePlotRange *yRange = [plotSpace.yRange mutableCopy];
[yRange expandRangeByFactor:CPTDecimalFromCGFloat(1.2f)];
plotSpace.yRange = yRange;

//Create styles and symbols

CPTMutableLineStyle *channelLineStyle = [channel1Plot.dataLineStyle mutableCopy];
channelLineStyle.lineWidth = 1.0;
channelLineStyle.lineColor = [CPTColor redColor];
channel1Plot.dataLineStyle = channelLineStyle;
channel2Plot.dataLineStyle = channelLineStyle;
channel3Plot.dataLineStyle = channelLineStyle;
channel4Plot.dataLineStyle = channelLineStyle;

}

-(void)configureAxes {

//Create styles
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor whiteColor];
axisTitleStyle.fontName = @"Helvetica-Bold";
axisTitleStyle.fontSize = 12.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [CPTColor whiteColor];
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor yellowColor];
axisTextStyle.fontName = @"Helvetica-Bold";
axisTextStyle.fontSize = 11.0f;
CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineWidth = 2.0f;
tickLineStyle.lineColor = [CPTColor yellowColor];
CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor purpleColor];
tickLineStyle.lineWidth = 1.0f;

//Get axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;

//Configure X-axis
CPTAxis *x = axisSet.xAxis;
x.title = @"Time";
x.titleTextStyle = axisTitleStyle;
x.titleOffset = 15.0f;
x.axisLineStyle = axisLineStyle;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.labelTextStyle = axisTextStyle;
x.majorTickLineStyle = axisLineStyle;
x.majorTickLength = 4.0f;
x.tickDirection = CPTSignNegative;
CGFloat pointsCount = POINTS_ON_SCREEN;
NSMutableSet *xLabels = [NSMutableSet setWithCapacity:pointsCount];
NSMutableSet *xLocations = [NSMutableSet setWithCapacity:pointsCount];
NSInteger i=0;
//NSString *loc = [NSString stringWithFormat:@"d",j];
for (NSInteger j=0; j<POINTS_ON_SCREEN; j++) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:@"%ld", (long)j+1] textStyle:x.labelTextStyle];
CGFloat location = i++;
label.tickLocation = CPTDecimalFromCGFloat(location);
label.offset = x.majorTickLength;
if (label) {
[xLabels addObject:label];
[xLocations addObject:[NSNumber numberWithFloat:location]];
}
}
x.axisLabels = xLabels;
x.majorTickLocations = xLocations;

//Configure Y-axis
axisSet.yAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
CPTAxis *y = axisSet.yAxis;
y.title = @"Channel outputs";
y.titleTextStyle = axisTitleStyle;
y.titleOffset = -40.0f;
y.axisLineStyle = axisLineStyle;
y.majorGridLineStyle = gridLineStyle;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelTextStyle = axisTextStyle;
y.labelOffset = 16.0f;
y.majorTickLineStyle = axisLineStyle;
y.majorTickLength = 4.0f;
y.minorTickLength = 2.0f;
y.tickDirection = CPTSignPositive;
CGFloat majorIncrement = 0.0005;
CGFloat minorIncrement = 0.0001;
CGFloat yMax = 0.0040f;
NSMutableSet *yLabels = [NSMutableSet set];
NSMutableSet *yMajorLocations = [NSMutableSet set];
NSMutableSet *yMinorLocations = [NSMutableSet set];
for (CGFloat j = minorIncrement; j<=yMax; j+=minorIncrement) {
j = roundf(j*100000)/100000;
CGFloat mod = j / majorIncrement;
NSInteger modInt = (NSInteger)mod;
CGFloat modMantissa = mod - modInt;
modMantissa = roundf(modMantissa * 100)/100;
if (modMantissa < 0.1 || modMantissa > 0.9) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:@"%.5f", j] textStyle:y.labelTextStyle];
NSDecimal location = CPTDecimalFromCGFloat(j);
//NSNumber *location = [NSNumber numberWithFloat:j];
label.tickLocation = location;
label.offset = -y.majorTickLength -y.labelOffset -9;
//label.offset = 0;
if (label) {
[yLabels addObject:label];
}
[yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];
} else {
[yMinorLocations addObject:[NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%f",j]]];
}
}
y.axisLabels = yLabels;
y.majorTickLocations = yMajorLocations;
y.minorTickLocations = yMinorLocations;
}

-(void)createTimer {
NSTimer *dataTimer = [NSTimer timerWithTimeInterval:0.002 target:self selector:@selector(dynamicUpdate:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:dataTimer forMode:NSDefaultRunLoopMode];
}

-(void)dynamicUpdate: (NSTimer *)dataTimer {
CPTGraph *graph = self.hostView.hostedGraph;
CPTPlot *channel1Plot = [graph plotWithIdentifier:@"channel1"];
CPTPlot *channel2Plot = [graph plotWithIdentifier:@"channel2"];
CPTPlot *channel3Plot = [graph plotWithIdentifier:@"channel3"];
CPTPlot *channel4Plot = [graph plotWithIdentifier:@"channel4"];
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;


if (channel1Plot && channel2Plot && channel3Plot && channel4Plot) {
if ( arrayIndex1 >= POINTS_ON_SCREEN-1
|| arrayIndex2 >= POINTS_ON_SCREEN-1
|| arrayIndex3 >= POINTS_ON_SCREEN-1
|| arrayIndex4 >= POINTS_ON_SCREEN-1) {

[channel1Array removeObjectAtIndex:0];
[channel1Plot deleteDataInIndexRange:NSMakeRange(0, 1)];
[channel2Array removeObjectAtIndex:0];
[channel2Plot deleteDataInIndexRange:NSMakeRange(0, 1)];
[channel3Array removeObjectAtIndex:0];
[channel3Plot deleteDataInIndexRange:NSMakeRange(0, 1)];
[channel4Array removeObjectAtIndex:0];
[channel4Plot deleteDataInIndexRange:NSMakeRange(0, 1)];
}

plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(currentIndex >= POINTS_ON_SCREEN ? currentIndex-POINTS_ON_SCREEN +1 : 0) length:CPTDecimalFromUnsignedInteger(POINTS_ON_SCREEN-1)];
currentIndex++;

[channel1Plot insertDataAtIndex:POINTS_ON_SCREEN-1 numberOfRecords:1];
[channel2Plot insertDataAtIndex:POINTS_ON_SCREEN-1 numberOfRecords:1];
[channel3Plot insertDataAtIndex:POINTS_ON_SCREEN-1 numberOfRecords:1];
[channel4Plot insertDataAtIndex:POINTS_ON_SCREEN-1 numberOfRecords:1];
}
}


-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
return POINTS_ON_SCREEN;
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx {
// NSLog(@"Plotting point");
NSNumber *num = nil;
if ([self.activityIndicator isAnimating] == YES) {
[self.activityIndicator stopAnimating];
}
switch (fieldEnum) {

case CPTScatterPlotFieldX:
if (idx < POINTS_ON_SCREEN) {
return [NSNumber numberWithUnsignedInteger:idx + currentIndex - POINTS_ON_SCREEN];
};
break;

case CPTScatterPlotFieldY:
if ([plot.identifier isEqual:@"channel1"]) {
num = [channel1Array objectAtIndex:idx];
arrayIndex1 = idx;
} else if ([plot.identifier isEqual:@"channel2"]) {
num = [channel2Array objectAtIndex:idx];
arrayIndex2 = idx;
} else if ([plot.identifier isEqual:@"channel3"]) {
num = [channel3Array objectAtIndex:idx];
arrayIndex3 = idx;
} else if ([plot.identifier isEqual:@"channel4"]) {
num = [channel4Array objectAtIndex:idx];
arrayIndex4 = idx;
} else {
NSLog(@"data unavailable");
}
break;

default:
NSLog(@"ERROR: trying to plot on unidentified axis");
break;
}
NSString *numString = [NSString stringWithFormat:@"%@", num];
dispatch_async(AddToArrayQ, ^{[self writeData:numString];});
return num;
}

最佳答案

除非我误读了这一点,否则您将从 numberOfRecordsForPlot: 返回一个硬编码值,因此 CorePlot 期望能够填充 x 轴上的所有这些点。您看到的那些行可能是由于将这些数组初始化为常量值(它们必须被初始化,对吧,否则当您尝试访问未初始化的索引时会出错?)

请注意,在 Eric Skroch 的示例中,他从 numberOfRecordsForPlot: 返回 [plotData count],并且 plotData 在初始化时为空。

关于ios - 使用 Core-Plot 的实时图上未说明的水平线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25733724/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com