Wilbe Wilbe - 5 months ago 25
Objective-C Question

Scatter plot y-Axis should not extend below the x-axis or yMin value

I have the following code to draw a scatter plot but I cannot get the y-axis to start labelling at the min value. The y-axis extends all the way to the minorIncrement float, but when I try and set the min value for the y axis it just disappears.

-(void)configureAxes {

// Calculate the increment values for the y-axis
DataSource *sharedManager = [DataSource sharedManager];
float ymax = -MAXFLOAT;
float ymin = MAXFLOAT;
for (NSNumber *num in sharedManager.finalFIELDreading) {
float y = num.floatValue;
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
int MinFieldReading = roundf(ymin);
int MaxFieldReading = roundf(ymax);
int diffFieldReading = MaxFieldReading-MinFieldReading;
int Increment = diffFieldReading/[sharedManager.finalFIELDreading count];
int incrementValue = 10 * floor( Increment / 10 + 0.5 );


// 1 - 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 whiteColor];
axisTextStyle.fontName = @"Helvetica-Bold";
axisTextStyle.fontSize = 11.0f;
CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor whiteColor];
tickLineStyle.lineWidth = 2.0f;
CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor blackColor];
tickLineStyle.lineWidth = 1.0f;

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

// 3 - Configure x-axis
NSArray *yMinNumbers = [sharedManager.finalFIELDreading sortedArrayUsingSelector:@selector(compare:)];// should determine dynamically based on max reading
CGFloat yMin = [yMinNumbers[0] floatValue];

// Set Axis to start just below the min y value
axisSet.xAxis.orthogonalPosition = @(yMin-40); //yMin-40
CPTAxis *x = axisSet.xAxis;
x.title = @"Station (m)";
x.titleTextStyle = axisTitleStyle;
x.titleOffset = 15.0f;
x.axisLineStyle = axisLineStyle;
x.majorGridLineStyle = gridLineStyle;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.labelTextStyle = axisTextStyle;
x.majorTickLineStyle = axisLineStyle;
x.majorTickLength = 4.0f;
x.tickDirection = CPTSignNegative;


CGFloat stationCount = [sharedManager.finalSTNreading count];


NSMutableSet *xLabels = [NSMutableSet setWithCapacity:stationCount];
NSMutableSet *xLocations = [NSMutableSet setWithCapacity:stationCount];
NSInteger i = 0;

for (NSString *station in [[DataSource sharedManager] finalSTNreading]) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:station textStyle:x.labelTextStyle];
CGFloat location = i++;
label.tickLocation = @(location);
label.offset = x.majorTickLength;
if (label) {
[xLabels addObject:label];
[xLocations addObject:[NSNumber numberWithFloat:location]];
}
}

x.axisLabels = xLabels;
x.majorTickLocations = xLocations;


// 4 - Configure y-axis

CPTAxis *y = axisSet.yAxis;
y.title = @"Field Reading (nTesla)";
y.titleTextStyle = axisTitleStyle;
y.titleOffset = 37.0f;
y.axisLineStyle = axisLineStyle;
y.majorGridLineStyle = gridLineStyle;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelTextStyle = axisTextStyle;
y.labelOffset = -7.0f;
y.majorTickLineStyle = axisLineStyle;
y.majorTickLength = 4.0f;
// y.minorTickLength = 2.0f;
y.tickDirection = CPTSignNegative;
NSInteger majorIncrement = incrementValue;
NSArray *yMaxNumbers = [[[DataSource sharedManager] finalFIELDreading] sortedArrayUsingSelector:@selector(compare:)];// should determine dynamically based on max reading
CGFloat yMax = [[yMaxNumbers lastObject] floatValue];
NSMutableSet *yLabels = [NSMutableSet set];
NSMutableSet *yMajorLocations = [NSMutableSet set];
for (NSInteger j = yMin; j <= yMax; j += majorIncrement) {

CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:@"%li", (long)j] textStyle:y.labelTextStyle];
NSNumber *location = @(j);
label.tickLocation = location;
label.offset = -y.majorTickLength - y.labelOffset;
if (label) {
[yLabels addObject:label];
}
[yMajorLocations addObject:location];

}
y.axisLabels = yLabels;
y.majorTickLocations = yMajorLocations;
}


enter image description here

Answer
  1. I don't see anywhere that you configure the plot space. That's what controls the visible data range on the graph. If you want the axes to stop before the edge of the plot area, set the visible range.

  2. The loop that creates y-labels should probably start at yMin, not minorIncrement. I suspect you're creating a lot of labels that will never appear on screen. This takes time to set up (affecting performance) and uses extra memory.

Comments