user1187378
user1187378

Reputation: 63

Core-plot - plotting very small numbers on scatter plot

On scatter plot, my x-coordinate data is just long numbers representing time in seconds since epoch whereas y-coordinate data looks like this: 0.675088, 0.670629, 0.669599. What I want to be showing as major ticks on the y axis is something like this: 0.64, 0.65, 0.66, 0.67 but what is currently shown on the chart is: 0.5, 0.7, 1.0, 1.2.

First of all, I don't know why I'm getting irregular tick interval as mentioned above (0.5 to 0.7 = 0.2, 0.7 to 1.0 = 0.3?) but I'm guessing because I was experimenting with the labeling policy and have set it to CPTAxisLabelingPolicyEqualDivisions - can someone please explain what all of these labeling policies mean?

The real question is what sort of value should I be using for majorIntervalLength on the y axis considering I'm plotting very small numbers? At the moment I have 0.01 but as I adjust this value by order of magnitude of -n, it doesn't actually make any difference to my chart.

This is a snippet of my code based on Plot_Gallery_iOS DatePlot.m

-(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme
{
CGRect bounds = layerHostingView.bounds;

NSDate *refDate = [NSDate dateWithTimeIntervalSince1970:0];
NSTimeInterval oneDay = 24 * 60 * 60;

CPTGraph *graph = [[[CPTXYGraph alloc] initWithFrame:bounds] autorelease];
[self addGraph:graph toHostingView:layerHostingView];
[self applyTheme:theme toGraph:graph withDefault:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];

[self setTitleDefaultsForGraph:graph withBounds:bounds];
[self setPaddingDefaultsForGraph:graph withBounds:bounds];

CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;

NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
NSTimeInterval threeMonthsago = now - (90*oneDay);

plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(threeMonthsago) length:CPTDecimalFromFloat(now - threeMonthsago)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.6f) length:CPTDecimalFromFloat(0.7f)];

NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateStyle = kCFDateFormatterShortStyle;
CPTTimeFormatter *timeFormatter = [[[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter] autorelease];
timeFormatter.referenceDate = refDate;

// Axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x          = axisSet.xAxis;
x.majorIntervalLength         = CPTDecimalFromFloat(oneDay*30);
x.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.6f);
x.minorTicksPerInterval       = 7;
x.labelFormatter            = timeFormatter;
x.labelRotation             = M_PI / 4;
x.preferredNumberOfMajorTicks = 5;

CPTXYAxis *y = axisSet.yAxis;
y.majorIntervalLength         = CPTDecimalFromDouble(0.001);
y.labelingPolicy = CPTAxisLabelingPolicyEqualDivisions;
y.preferredNumberOfMajorTicks = 5;
y.minorTicksPerInterval       = 10;
y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(now);
//    y.visibleRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.6f) length:CPTDecimalFromFloat(0.1f)];
CPTScatterPlot *dataSourceLinePlot = [[[CPTScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = @"Date Plot";

// [plotSpace scaleToFitPlots:[NSArray arrayWithObjects:dataSourceLinePlot, nil]];

CPTMutableLineStyle *lineStyle = [[dataSourceLinePlot.dataLineStyle mutableCopy] autorelease];
lineStyle.lineWidth              = .5f;
lineStyle.lineColor              = [CPTColor greenColor];
dataSourceLinePlot.dataLineStyle = lineStyle;

// Auto scale the plot space to fit the plot data
// Extend the ranges by 30% for neatness
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:dataSourceLinePlot, nil]];
CPTMutablePlotRange *xRange = [[plotSpace.xRange mutableCopy] autorelease];
CPTMutablePlotRange *yRange = [[plotSpace.yRange mutableCopy] autorelease];
[xRange expandRangeByFactor:CPTDecimalFromDouble(1.3)];
[yRange expandRangeByFactor:CPTDecimalFromDouble(1.3)];
plotSpace.xRange = xRange;
plotSpace.yRange = yRange;

dataSourceLinePlot.dataSource = self;
[graph addPlot:dataSourceLinePlot];
 }

UPDATE:

Solved the problem by setting custom y major ticks by doing this:

y.labelingPolicy = CPTAxisLabelingPolicyLocationsProvided;

NSSet *majorTickLoc = [NSSet setWithObjects:[NSDecimalNumber numberWithFloat:0.64f], [NSDecimalNumber numberWithFloat:0.65f], [NSDecimalNumber numberWithFloat:0.66f], [NSDecimalNumber numberWithFloat:0.67f],[NSDecimalNumber numberWithFloat:0.68f],nil];
y.majorTickLocations = majorTickLoc;

But the number still appeared to be rounded i.e. having only one fraction digit 0.6, 0.7, 0.7 etc and turns out that's just the labelling. Setting number formatter on the label works:

NSNumberFormatter *yFormatter = [[NSNumberFormatter alloc] init];
[yFormatter setMinimumFractionDigits:4];
[yFormatter setMaximumFractionDigits:4];
[yFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
y.labelFormatter = yFormatter;

Upvotes: 2

Views: 975

Answers (2)

Eric Skroch
Eric Skroch

Reputation: 27381

Set the labelFormatter for the y-axis.

NSNumberFormatter *newFormatter = [[[NSNumberFormatter alloc] init] autorelease];
newFormatter.minimumIntegerDigits = 1;
newFormatter.maximumFractionDigits = 2;
newFormatter.minimumFractionDigits = 2;
y.labelFormatter = newFormatter;

Upvotes: 0

Dinesh
Dinesh

Reputation: 6532

Try this following code :

y.majorIntervalLength = CPTDecimalFromString(@"0.1")

Upvotes: 0

Related Questions