iOS CorePlot numeric formatting of y-axis - ios

I'm working with Core Plot 1.1 to draw a simple scatter plot in iOS6. I am using the following code to properly format my y-axis which then dynamically scales to the plot data.
CPTXYAxis *y = axisSet.yAxis;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.minorTicksPerInterval = 3;
y.preferredNumberOfMajorTicks = 6;
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
...
NSNumberFormatter * yformatter = [[NSNumberFormatter alloc] init];
[yformatter setUsesSignificantDigits:YES];
[yformatter setMaximumSignificantDigits:4];
[yformatter setMaximumFractionDigits:1];
[yformatter setRoundingMode:NSNumberFormatterRoundCeiling];
y.labelFormatter = yformatter;
Then I dynamically change the range based on the data to be plotted using maxPlotValue but bound it to a minimum.
plotSpace.xRange = [CPTPlotRange
plotRangeWithLocation:CPTDecimalFromFloat(0)
length:CPTDecimalFromFloat(5)];
plotSpace.yRange = [CPTPlotRange
plotRangeWithLocation:CPTDecimalFromFloat(0)
length:CPTDecimalFromFloat(maxPlotValue)];
This works great in most cases but sometimes I get a strange formatting error like in the below fig 1 where 0.6001 is displayed in stead of 0.6. If I manually change the minimum range to 2 the error disappears.
The reason I'm using 4 significant digits is that I can have numbers up to 8000 and then they are displayed without the fraction. If I change the setMaximumSignificantDigits to 3 I get 0.601 which I guess indicates that the problem is with the CPTAxisLabelingPolicyAutomatic.
Any help on this would be greatly appreciated.
Fig 1, Error in formatting:
https://dl.dropbox.com/u/8083213/fig_1.png
Fig 2, No error in formatting:
https://dl.dropbox.com/u/8083213/fig_2.png

This sounds like a rounding error in the labeling calculations. Please report it on the Core Plot issue tracker.

Related

CorePlot Visible Range Not Working As Expected

So I've been modifying the sample code to try to have a graph show the y values of 0-20 and to only show the max of 6 x values on the screen at a time. A visible range of 0-6 for x;
Here's a picture of what I'm shooting for
And this is what it looks like
So here's the part of the code I think is most important. Here I'll show you how I made the visible Axis Range, plot space ranges and plot space global ranges:
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
CPTMutablePlotRange *yRange = [plotSpace.yRange mutableCopy];
// I'm not sure what the difference is between the two
// constrict this to 0-20 for y and 0-6 for x
x.visibleRange = nil;
y.visibleRange = nil;
x.visibleAxisRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(6.f)];
y.visibleAxisRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(20.f)];
// expand the X, y axis to be more than we need
[xRange expandRangeByFactor:CPTDecimalFromDouble(1.05)];
[yRange expandRangeByFactor:CPTDecimalFromDouble(1.05)];
plotSpace.xRange = xRange;
plotSpace.yRange = yRange;
// expand it to be even bigger
[xRange expandRangeByFactor:CPTDecimalFromDouble(3.0)];
[yRange expandRangeByFactor:CPTDecimalFromDouble(3.0)];
plotSpace.globalXRange = xRange;
plotSpace.globalYRange = yRange;
So in the picture of what is displayed on the app, seems to shows all my values instead of just the six, but it seems to know that I only want to show 6 since the labels stop at six. I'd like to get the app to scroll left and right to show the other points after I get it to show the proper length of the line, but one thing at a time.
Here's the code. It's pretty sloppy, I was just hacking around to see what was possible before I clean it up and bring it to my real project. All the work is done in the controlChart.m file, I mucked around with some of the Plain White theme file but that should be unimportant.
coreplot-horrible-code
Since the x data points are one unit apart, giving the xRange a length of 6 (plus a bit for the plot symbols) will do what you want. In the code you posted, the xRange is set up with -scaleToFitPlots: before expanding the range. This makes it fit all of the plot data.

How to show the graph with high data in a given space?

I am using Line Graph of Core Plot in my project. The thing is when I kept the data of my X-axis and Y-axis like: 1,2,3....10, everything worked fine. But now the data is like: X-axis: 0, 150, 500.... and on Y-axis: 0,1000,2000 and so on.
So now my graph is not fully visible in the given area. I know it is because the range on my Y-axis is getting too high and it is not visible. Some code that might possibly the reason for it:
// Setup scatter plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0.0) length:CPTDecimalFromInteger(8)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0.0) length:CPTDecimalFromInteger(5)];
// Restrict y range to a global range
CPTPlotRange *globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-2.5)
length:CPTDecimalFromDouble(5.0)];
plotSpace.globalYRange = globalYRange;
CPTPlotRange *globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-0.2)
length:CPTDecimalFromDouble(17.0)];
plotSpace.globalXRange=globalXRange;
The xRange and yRange are too small to display all of the plot data.
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0)
length:CPTDecimalFromInteger(500)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0)
length:CPTDecimalFromInteger(2000)];
No luck :( It becomes as per its shown above. I dont want to compress the data. The distance between the months should be as same as the figure posted in the question. The Y axis data is still not getting visible completely. My global X and Y range is like this
CPTPlotRange *globalYRange = [CPTPlotRange
plotRangeWithLocation:CPTDecimalFromDouble(-2.5)
length:CPTDecimalFromDouble(5.0)];
plotSpace.globalYRange = globalYRange;
CPTPlotRange *globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-0.2)
length:CPTDecimalFromDouble(17.0)];
plotSpace.globalXRange=globalXRange;

Core Plot : show time in x-axis

I am newbie of Core Plot. I have data of time and temperature data. I am using CPTXYGraph to plot Y-axis (temperature) and X-axis (time in minutes). But I have no idea to show the x-axis in format 01:00, 01:15 etc ?
What I'm missing?
All you need to do is to assign a label formatter for the x-axis to print the time values as you want it. Use something like this:
CPTXYAxis *x = axisSet.xAxis;
x.labelTextStyle = textStyle; // a CPTTextStyle you created for color/font etc.
NSDateFormatter *formatter = [NSDateFormatter alloc] initWithDateFormat: #"mm:ss" allowNaturalLanguage: NO];
x.labelFormatter = formatter;

CorePlot: Centering Ticks on right-aligned Y Axis

I'm using CorePlot to draw a bar chart according to a specific design, and I'm having trouble getting the ticks on my Y-Axis centred. By that I mean that half the tick should be on the left side of the axis, and the other half on the right.
Here's the code I'm using so far:
CPTLineStyle *majorTickStyle = [[CPTMutableLineStyle alloc] init];
majorTickStyle.lineColor = GlobalColors.lightPinkColor.CPTColor;
CPTLineStyle *minorTickStyle = [[CPTMutableLineStyle alloc] init];
minorTickStyle.lineColor = GlobalColors.greyColor.CPTColor;
CPTXYAxis *y = axisSet.yAxis;
//y.titleOffset = 50.0f;
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
y.axisConstraints = [CPTConstraints constraintWithUpperOffset:0];
y.tickDirection = CPTSignPositive;
y.majorTickLineStyle = majorTickStyle;
y.majorTickLength = 10;
y.minorTickLineStyle = minorTickStyle;
y.labelTextStyle = axisLabelStyle;
The image on the left is what the code above gave me, and the right is what the designer presented (i.e. what I'm trying to achieve):
(I'm not too worried abut the number of ticks, and the "L" on the end of the number is a separate issue entirely)
This isn't supported right now. Please add an enhancement request on the Core Plot issue tracker.
In the mean time, you could use custom axis labels (CPTAxisLabelingPolicyNone) and offset the label locations from the tick locations slightly.
If your app requires iOS 6 or later, Core Plot added support for attributed text in labels after release 1.2. This would make adding the small "L" easy. This would also require custom axis labels.

Force grid lines to update when range changes in Core-Plot scatter plot on iOS

I have a CPTXYGraph with a CPTScatterPlot, which I update with new data using [graph reloadData]. I also set the ranges based on the data. My problem is that though the axes update fine when the range changes, the gridlines do not, so I end up with this http://inky.ws/g/hw (no grid lines at the end of the x-axis).
I set axis.gridLinesRange = nil, and I tried re-setting all the gridline properties when updating ranges, to no avail.
To clarify, the original plot looks fine, but when I update with a bigger data set, the grid lines are missing in the added range.
I've had the same issue and used the following workaround: calculate new bounds of your values and replace the default plot space range with a new one using the plotRangeWithLocation:length: convenience method.
Not very satisfying performance-wise and conceptually (feels a bit like doing the job of the framework) but it worked for me.
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat([valuesMin floatValue]) length:CPTDecimalFromFloat([valuesMax floatValue]-[valuesMin floatValue])];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *y = axisSet.yAxis;
float amplitude = ([valuesMax floatValue]-[valuesMin floatValue]);
NSDecimal intervalLength = CPTDecimalFromFloat(100);
y.majorIntervalLength = intervalLength;

Resources