Scatter Plot Axis Formatting

12 views
Skip to first unread message

Joshua ONeal

unread,
Oct 23, 2010, 3:33:37 PM10/23/10
to coreplot-discuss
Quick question(s). I've modded the scatter plot sample app to fit what
I need, but I'd like to refine the axes further.

1. Y-Axis: This represents a dollar amount. As of now it shows
$4,349.30 as 4349.3. I'd like to format it a bit with this method:

- (NSString *)formatStringFromString:(NSString *)inputString
{
NSNumberFormatter *helperFormatter = [[[NSNumberFormatter alloc]
init] autorelease];

[helperFormatter setPositiveFormat:@"$#,##0.00"];
[helperFormatter setNegativeFormat:@"-$#,##0.00"];

NSNumber *helperNumber = [NSNumber numberWithFloat:[inputString
floatValue]];

return [helperFormatter stringFromNumber:helperNumber];
}

Here is the code that returns the X/Y values, I notice it returns an
NSNumber, is there a way I can specify a formatter to return it nice
looking?

-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum
recordIndex:(NSUInteger)index
{
// line
if( [self.whichChart isEqualToString:@"Line"] )
{
if([plot.identifier isEqual:@"Asset Plot"])
{
NSNumber *num = [[assetLineData objectAtIndex:index] valueForKey:
(fieldEnum == CPScatterPlotFieldX ? @"x" : @"y")];
return num;
}
}
}

2. For the X-axis, I just have it returning 1.0, 2.0, 3.0 etc, but I
want it to correspond to a calendar date. Is there once again, a way
to mod or use a different function than, numberForPlot? Instead of
returning 1.0, I'd like to return @"10/10/2010", etc. I can just make
them correspond to an NSDictionary etc.

3. It occurs to me that maybe number for plot isn't the place to do
this, but if there is a different place / method could you tell me?
I'll look in the headers in the mean time.

Here is a quick graphic:

Current:

Y:
1234.2

123.3

1234.23

X:
1.0

2.0

3.0

Target:

Y:
$1,234.20

$123.30

$1,234.23

X:
(perhaps corresponding to an array key, etc

10/01/2010

10/04/2010

11/14/2010

Thanks so much, and sorry if any of this is rambley, the girlfriend is
having a baby shower for her friend atm, so I can't focus too well :p

- Josh

Eric

unread,
Oct 23, 2010, 4:30:45 PM10/23/10
to coreplot-discuss
#1. Use the labelFormatter property on the y-axis to format the
labels. It's a standard NSNumberFormatter, so the one in your example
above should work fine.

#2 & 3. See DatePlot in the examples folder. You'll have to convert
your dates to a common scale and use a formatter to output them as
dates. There's an open issue (http://code.google.com/p/core-plot/
issues/detail?id=144) to allow you to provide NSDates directly from
the datasource, but that's a pretty low priority right now and no
guarantees about when it'll be implemented.

Eric

Joshua ONeal

unread,
Oct 23, 2010, 4:54:17 PM10/23/10
to coreplot-discuss
1.) This worked great, thanks! :

CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPDecimalFromFloat(yFloat/dCount);
y.orthogonalCoordinateDecimal = CPDecimalFromString(@"0");
y.minorTicksPerInterval = 1;

NSNumberFormatter *helperFormatter = [[NSNumberFormatter alloc]
init];

[helperFormatter setPositiveFormat:@"$#,##0.00"];
[helperFormatter setNegativeFormat:@"-$#,##0.00"];

y.labelFormatter = helperFormatter;

[helperFormatter release];

2. Will look into, not sure exactly what you mean by common scale
though.

Thanks!

- Josh

Joshua ONeal

unread,
Oct 24, 2010, 10:26:39 PM10/24/10
to coreplot-discuss
Well I got it to kinda work, but for whatever reason all of my data is
stacking up on top of itself, all on one day:

http://lifecoderdev.com/charts.jpg

When I NSLog() my X values, they all come out as the proper increments
from my reference date. Any initial thoughts as to why this is
happening?

I can provide a large chunk of code, if need be.

Thanks!

- Josh

Eric

unread,
Oct 24, 2010, 11:15:31 PM10/24/10
to coreplot-discuss
You need to check the xRange of your plot space and compare that with
your data points. Since the x-axis labels look ok, the range probably
is, too, but it's worth checking. Also make sure that your datasource
returns the correct values for each field.

Eric

Joshua ONeal

unread,
Oct 25, 2010, 1:48:20 PM10/25/10
to coreplot-discuss
Here is the X range setter:

NSTimeInterval oneDay = 24 * 60 * 60;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;

plotSpace.xRange = [CPPlotRange
plotRangeWithLocation:CPDecimalFromFloat(0.0f)
length:CPDecimalFromFloat(oneDay*5.0f)];
plotSpace.yRange = [CPPlotRange
plotRangeWithLocation:CPDecimalFromFloat(-0.75)
length:CPDecimalFromFloat(yFloat+(yFloat/4))];

I get my objects from an sqlite query that will have at most, 5
objects. And yFloat is the highest dollar amount on the Y asis.

Here is the output of the number for plot:

2010-10-25 12:44:50.384 X[465:207] account: which: 0 value: 0
2010-10-25 12:44:50.385 X[465:207] account: which: 0 value: 0
2010-10-25 12:44:50.386 X[465:207] account: which: 0 value: 1
2010-10-25 12:44:50.387 X[465:207] account: which: 0 value: 1
2010-10-25 12:44:50.388 X[465:207] account: which: 0 value: 3
2010-10-25 12:44:50.389 X[465:207] account: which: 1 value: 12264.53
2010-10-25 12:44:50.390 X[465:207] account: which: 1 value: 12264.53
2010-10-25 12:44:50.390 X[465:207] account: which: 1 value: 7964.51
2010-10-25 12:44:50.391 X[465:207] account: which: 1 value: -1035.32
2010-10-25 12:44:50.392 X[465:207] account: which: 1 value: -1035.32
2010-10-25 12:44:50.394 X[465:207] stock: which: 0 value: 0
2010-10-25 12:44:50.395 X[465:207] stock: which: 0 value: 0
2010-10-25 12:44:50.395 X[465:207] stock: which: 0 value: 1
2010-10-25 12:44:50.396 X[465:207] stock: which: 0 value: 1
2010-10-25 12:44:50.396 X[465:207] stock: which: 0 value: 3
2010-10-25 12:44:50.397 X[465:207] stock: which: 1 value: 1215.96
2010-10-25 12:44:50.398 X[465:207] stock: which: 1 value: 607.98
2010-10-25 12:44:50.398 X[465:207] stock: which: 1 value: 607.98
2010-10-25 12:44:50.399 X[465:207] stock: which: 1 value: 607.98
2010-10-25 12:44:50.399 X[465:207] stock: which: 1 value: 645.13
2010-10-25 12:44:50.401 X[465:207] liability: which: 0 value: 0
2010-10-25 12:44:50.402 X[465:207] liability: which: 0 value: 0
2010-10-25 12:44:50.402 X[465:207] liability: which: 0 value: 1
2010-10-25 12:44:50.403 X[465:207] liability: which: 0 value: 1
2010-10-25 12:44:50.404 X[465:207] liability: which: 0 value: 3
2010-10-25 12:44:50.404 X[465:207] liability: which: 1 value: 6699.9
2010-10-25 12:44:50.405 X[465:207] liability: which: 1 value: 669.99
2010-10-25 12:44:50.406 X[465:207] liability: which: 1 value: 669.99
2010-10-25 12:44:50.407 X[465:207] liability: which: 1 value: 669.99
2010-10-25 12:44:50.408 X[465:207] liability: which: 1 value: 793.23
2010-10-25 12:44:50.410 X[465:207] asset: which: 0 value: 0
2010-10-25 12:44:50.411 X[465:207] asset: which: 0 value: 0
2010-10-25 12:44:50.412 X[465:207] asset: which: 0 value: 1
2010-10-25 12:44:50.413 X[465:207] asset: which: 0 value: 1
2010-10-25 12:44:50.413 X[465:207] asset: which: 0 value: 3
2010-10-25 12:44:50.414 X[465:207] asset: which: 1 value: 500
2010-10-25 12:44:50.414 X[465:207] asset: which: 1 value: 500
2010-10-25 12:44:50.415 X[465:207] asset: which: 1 value: 500
2010-10-25 12:44:50.415 X[465:207] asset: which: 1 value: 500
2010-10-25 12:44:50.417 X[465:207] asset: which: 1 value: 500

Where asset/account/stock/liability is one of the 4 lines on the plot,
which is 0 = x, 1 = y, and value is the value.

I am just stumped.

Your thoughts?

Thanks so much for everything so far!

- Josh

Eric

unread,
Oct 25, 2010, 9:53:56 PM10/25/10
to coreplot-discuss
The data you posted looks ok to me. I assume that's a dump of your
internal data structure. Did you double-check your datasource method
to make sure it's returning the right data for each field (x for x, y
for y, and the correct indices)?

Eric

Joshua ONeal

unread,
Oct 26, 2010, 4:29:19 PM10/26/10
to coreplot-discuss
Well I figured it out. Turns out I misunderstood :p I was returning my
X values as days since the reference date. I didn't realize they were
supposed to be in seconds since the reference date!!! What I thought
was 2 or 3 days past the date was only 2 or 3 /seconds/!

It works great now, but I have one final question. When I load the
graph, the Y and X axes are on the farthest left, and bottom
respectively pixels of the plot area. And since the labels are on the
left and bottom of the axes, respectively, the user has to drag the
graph in an up-right motion, to display the axis labels. Is there a
way to make the X and Y axis draw, possibly, a fixed space from the
bottom and left side of the whole plot? Maybe like 20 px from the
bottom and 50 from the left?

Thanks!

- Josh

Joshua ONeal

unread,
Oct 26, 2010, 4:42:29 PM10/26/10
to coreplot-discuss
And when I say move the axes, I don't mean the
orthogonalCoordinateDecimal, I mean, is there a way to shift the (0,0)
origin physically up and right by 10px when the graph is drawn?

Thanks!

- Josh

On Oct 25, 8:53 pm, Eric <eskr...@mac.com> wrote:

Eric

unread,
Oct 26, 2010, 6:42:18 PM10/26/10
to coreplot-discuss
You can add some padding and adjust the visible range of your axes.
See http://groups.google.com/group/coreplot-discuss/browse_thread/thread/3178bdad350aa2a6
and the thread linked from there.

Eric
> > > > > > > > Thanks so much, and sorry if any of this is rambley, the girlfriend is...
>
> read more »
Reply all
Reply to author
Forward
0 new messages