Add additional x axes in core-plot - ios

I want to add multiple x-axis, My code is as follows:
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)barChart.axisSet;
/// Here I customize default x and y axis. And they are correctly visible
// Now create additional x axis
CPTXYAxis *bottomX = [[CPTXYAxis alloc]init];
bottomX.orthogonalCoordinateDecimal = CPTDecimalFromString(#"4");
CPTMutableLineStyle * lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.lineWidth = 3.0f;
lineStyle.lineColor = [CPTColor greenColor];
lineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:5.0f], [NSNumber numberWithFloat:5.0f], nil];
bottomX.axisLineStyle = lineStyle;
NSMutableArray * axes=[NSMutableArray arrayWithArray:axisSet.axes];
[axes addObject:bottomX];
axisSet.axes=axes;
The default x,y axes are perfect, but the additional x axis (bottomX) is not showing any where.

You need to set the plot space on the new axis:
bottomX.plotSpace = barChart.defaultPlotSpace;

Related

How to set bounds on a plotspace in CorePlot?

I am trying to draw multiple scatter plots on the same graph using Core-Plot. They have the same x-axis (time), but I want them to be drawn independently of each other. For eg, for two plots, I want the screen to be divided into two parts, the upper part showing one plot and the lower part showing the other (I intend to ultimately plot a real-time multi-channel input). Something like this:
I tried modifying the tutorial given in the following link to use two plotspaces instead of one:
http://www.raywenderlich.com/13271/how-to-draw-graphs-with-core-plot-part-2
However, there is no function to set the bounds of a plotspace. The functions xRange and yRange change the range of the axes, but both the plotspaces still occupy the whole screen.
Following is a code snippet that shows two ways in which I tried to accomplish setting bounds:
-(void)configurePlots {
//Get graph and plot space
CPTGraph *graph = self.hostView.hostedGraph;
CPTXYPlotSpace *aaplPlotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
//**Setting xRange and yRange doesn't work**
aaplPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(0.0)
length:CPTDecimalFromCGFloat(graph.bounds.size.width)];
aaplPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(0.0)
length:CPTDecimalFromCGFloat((graph.bounds.size.height)/3)];
CPTXYPlotSpace *googPlotSpace = [[CPTXYPlotSpace alloc] init];
googPlotSpace.xRange = aaplPlotSpace.xRange;
googPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat((graph.bounds.size.height)/3)
length:CPTDecimalFromCGFloat((graph.bounds.size.height)/3)];
[graph addPlotSpace:googPlotSpace];
//Create Plots
//**Trying to set bounds using initWithFrame doesn't work either**
CGRect rect = CGRectMake(0.0, 0.0, graph.bounds.size.width, graph.bounds.size.height/2);
CPTScatterPlot *aaplPlot = [[CPTScatterPlot alloc] initWithFrame:rect];
aaplPlot.dataSource = self;
aaplPlot.identifier = CPDTickerSymbolAAPL;
CPTColor *aaplColor = [CPTColor redColor];
[graph addPlot:aaplPlot toPlotSpace:aaplPlotSpace];
rect = CGRectMake(0.0, graph.bounds.size.height/2, graph.bounds.size.width, graph.bounds.size.height/2);
CPTScatterPlot *googPlot = [[CPTScatterPlot alloc] initWithFrame:rect];
googPlot.dataSource = self;
googPlot.identifier = CPDTickerSymbolGOOG;
CPTColor *googColor = [CPTColor greenColor];
[graph addPlot:googPlot toPlotSpace:googPlotSpace];
//[graph addPlot:googPlot];
//Set up Plot space
[aaplPlotSpace scaleToFitPlots:[NSArray arrayWithObject:aaplPlot]];
CPTMutablePlotRange *xaRange = [aaplPlotSpace.xRange mutableCopy];
[xaRange expandRangeByFactor:CPTDecimalFromCGFloat(1.1f)];
aaplPlotSpace.xRange = xaRange;
CPTMutablePlotRange *yaRange = [aaplPlotSpace.yRange mutableCopy];
[yaRange expandRangeByFactor:CPTDecimalFromCGFloat(1.2f)];
aaplPlotSpace.yRange = yaRange;
//Create styles and symbols
CPTMutableLineStyle *aaplLineStyle = [aaplPlot.dataLineStyle mutableCopy];
aaplLineStyle.lineWidth = 2.5;
aaplLineStyle.lineColor = aaplColor;
aaplPlot.dataLineStyle = aaplLineStyle;
CPTMutableLineStyle *aaplSymbolLineStyle = [CPTMutableLineStyle lineStyle];
aaplSymbolLineStyle.lineColor = aaplColor;
CPTPlotSymbol *aaplSymbol = [CPTPlotSymbol ellipsePlotSymbol];
aaplSymbol.fill = [CPTFill fillWithColor:aaplColor];
aaplSymbol.lineStyle = aaplSymbolLineStyle;
aaplSymbol.size = CGSizeMake(6.0f, 6.0f);
aaplPlot.plotSymbol = aaplSymbol;
CPTMutableLineStyle *googLineStyle = [googPlot.dataLineStyle mutableCopy];
googLineStyle.lineWidth = 1.0;
googLineStyle.lineColor = googColor;
googPlot.dataLineStyle = googLineStyle;
CPTMutableLineStyle *googSymbolLineStyle = [CPTMutableLineStyle lineStyle];
googSymbolLineStyle.lineColor = googColor;
CPTPlotSymbol *googSymbol = [CPTPlotSymbol starPlotSymbol];
googSymbol.fill = [CPTFill fillWithColor:googColor];
googSymbol.lineStyle = googSymbolLineStyle;
googSymbol.size = CGSizeMake(6.0f, 6.0f);
googPlot.plotSymbol = googSymbol;
}
My question is, is my current approach correct in trying to set bounds on plotspaces or do I need to draw different graphs on the same screen and set the bounds on the graphs? And how do I set bounds on plotspaces or graphs (whichever is the right way!)?
Thanks!

Core Plot graph bottom axis not visible

I've got a core-plot line graph which is displaying as follows (background view coloured red for clarity):
I have 0 padding at the bottom, and I have an x-axis configured, with labels. The graph is squeezed right down against the bottom of the view though. If I increase the bottom padding I get a grey bar at the bottom with the same result.
What do I need to change in order to move the graph up from the bottom of the view and display the axis?
The code is quite lengthy, but here's some excerpts:
self->graph = [[CPTXYGraph alloc] initWithFrame:hostView.bounds];
hostView.hostedGraph = graph;
self->graph.paddingLeft = 0.0f;
self->graph.paddingTop = 10.0f;
self->graph.paddingRight = 0.0f;
self->graph.paddingBottom = 0.0f;
...
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:p1, p2, p3, nil]];
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
[xRange expandRangeByFactor:CPTDecimalFromCGFloat(1.1f)];
plotSpace.xRange = xRange;
CPTMutablePlotRange *yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(500.0f)];
plotSpace.yRange = yRange;
...
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self->graph.axisSet;
CPTAxis *x = axisSet.xAxis;
x.axisLineStyle = axisLineStyle;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.majorTickLineStyle = axisLineStyle;
x.majorTickLength = 4.0f;
x.tickDirection = CPTSignNegative;
...
x.axisLabels = xLabels;
x.majorTickLocations = xLocations;
Try adding bottom padding to graph.plotAreaFrame.

Core Plot doesn't draw the axes, why?

I'm learning Core Plot and I've come to draw the following graph of the sinus function with Core Plot 1.2:
As you see, the axes aren't drawn, even if I configure my axes as in the following snippet.
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [CPTColor blackColor];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.axisLineStyle = axisLineStyle;
axisSet.yAxis.axisLineStyle = axisLineStyle;
My question is: Why the axes aren't shown? How can I force CorePlot to draw them?.
Here's the full relevant code:
-(void)viewDidLoad
{
[super viewDidLoad];
self.graph = [[CPTXYGraph alloc] initWithFrame:self.view.frame];
CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.view;
hostingView.hostedGraph = self.graph;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-4) length:CPTDecimalFromFloat(8)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-2.0) length:CPTDecimalFromFloat(4.0)];
CPTScatterPlot *sinusPlot = [[CPTScatterPlot alloc] initWithFrame:self.graph.frame];
sinusPlot.dataSource = self;
sinusPlot.backgroundColor = [CPTColor whiteColor].cgColor;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [CPTColor blackColor];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.axisLineStyle = axisLineStyle;
axisSet.yAxis.axisLineStyle = axisLineStyle;
[self.graph addPlot:sinusPlot];
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return 101;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx
{
static double pi = 3.14159;
double x = pi*((((double)idx) - 51.0)/50.0);
if (fieldEnum == CPTScatterPlotFieldX)
return [NSNumber numberWithDouble:x];
else
return [NSNumber numberWithDouble:sin(x + ((x<0)?2*pi:0))];
}
Adding the following line:
self.graph.backgroundColor = [CPTColor whiteColor].cgColor;
to viewDidLoad solved the issue.
My explanation is that the axis set is a property of the CPTGraphHostingView (here self.graph), and not of the plot. I was changing the plot's layer background color instead of changing the graph's layer background color. Since the axes still had the same color as the background of their containing layer, they weren't visible.
For future reference, a simple working version of viewDidLoad, is the following:
-(void)viewDidLoad
{
[super viewDidLoad];
self.graph = [[CPTXYGraph alloc] initWithFrame:self.view.frame];
CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.view;
hostingView.hostedGraph = self.graph;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-4) length:CPTDecimalFromFloat(8)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-2.0) length:CPTDecimalFromFloat(4.0)];
CPTScatterPlot *sinusPlot = [[CPTScatterPlot alloc] initWithFrame:self.graph.frame];
sinusPlot.dataSource = self;
self.graph.backgroundColor = [CPTColor whiteColor].cgColor;
[self.graph addPlot:sinusPlot];
}
I hope this will help CorePlot rookies like my current self.

Core Plot: Additional axis not shown

I have added an additional x axis to my plot space in order to show zero values:
CPTMutableLineStyle *boldLineStyle = [xAxis.axisLineStyle mutableCopy];
boldLineStyle.lineWidth = 1;
boldLineStyle.lineColor = [CPTColor darkGrayColor];
boldLineStyle.lineCap = kCGLineCapRound;
CPTXYAxis *xZeroAxis = [[CPTXYAxis alloc] init];
xZeroAxis.coordinate = CPTCoordinateX;
xZeroAxis.plotSpace = plotSpace;
xZeroAxis.axisLineStyle = boldLineStyle;
Interestingly, the labels on this axis are shown, but not the axis itself:
xZeroAxis.axisLabels = [NSSet setWithArray:naLabels];
xZeroAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
xyAxisSet.axes = #[xAxis, xLabelAxis, yAxis, xZeroAxis];
How would I need to change my code to show the x axis?
Thank you!
x.axisLineStyle is set as follows:
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 1.0;
axisLineStyle.lineCap = kCGLineCapRound;
axisLineStyle.lineColor = [CPTColor darkGrayColor];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPPTXYAxis *x = axisSet.xAxis;
x.axisLineStyle = axisLineStyle;
This seems to be a bug in the current Core Plot release. The issue has been reported here: Core Plot Issue 514

Two graphs in core plot that can function simultaneously

I'm trying to plot two sets of data wrt to time on the same page and hence i need two different X and Y axis. Here is the sample code I'm working with:
-(void)initialisePlot
{
// Start with some simple sanity checks before we kick off
if ( (self.hostingView == nil) || (self.graphData == nil) ) {
NSLog(#"TUTSimpleScatterPlot: Cannot initialise plot without hosting view or data.");
return;
}
if ( self.graph != nil ) {
NSLog(#"TUTSimpleScatterPlot: Graph object already exists.");
return;
}
// Create a graph object which we will use to host just one scatter plot.
CGRect frame = [self.hostingView bounds];
self.graph = [[CPTXYGraph alloc] initWithFrame:frame];
// Add some padding to the graph, with more at the bottom for axis labels.
self.graph.plotAreaFrame.paddingTop = 20.0f;
self.graph.plotAreaFrame.paddingRight = 20.0f;
self.graph.plotAreaFrame.paddingBottom = 50.0f;
self.graph.plotAreaFrame.paddingLeft= 20.0f;
// Tie the graph we've created with the hosting view.
self.hostingView.hostedGraph = self.graph;
// If you want to use one of the default themes - apply that here.
[self.graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
// Create a line style that we will apply to the axis and data line.
CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.lineColor = [CPTColor redColor];
lineStyle.lineWidth = 2.0f;
// Create a text style that we will use for the axis labels.
CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
textStyle.fontName = #"Helvetica";
textStyle.fontSize = 14;
textStyle.color = [CPTColor blackColor];
// Create the plot symbol we're going to use.
CPTPlotSymbol *plotSymbol = [CPTPlotSymbol hexagonPlotSymbol];
plotSymbol.lineStyle = lineStyle;
plotSymbol.size = CGSizeMake(8.0, 8.0);
// Setup some floats that represent the min/max values on our axis.
float xAxisMin = -10;
float xAxisMax = 10;
float yAxisMin = 0;
float yAxisMax = 100;
// We modify the graph's plot space to setup the axis' min / max values.
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xAxisMin) length:CPTDecimalFromFloat(xAxisMax - xAxisMin)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yAxisMin) length:CPTDecimalFromFloat(yAxisMax - yAxisMin)];
// Modify the graph's axis with a label, line style, etc.
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.title = #"Data X";
axisSet.xAxis.titleTextStyle = textStyle;
axisSet.xAxis.titleOffset = 30.0f;
axisSet.xAxis.axisLineStyle = lineStyle;
axisSet.xAxis.majorTickLineStyle = lineStyle;
axisSet.xAxis.minorTickLineStyle = lineStyle;
axisSet.xAxis.labelTextStyle = textStyle;
axisSet.xAxis.labelOffset = 3.0f;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(2.0f);
axisSet.xAxis.minorTicksPerInterval = 1;
axisSet.xAxis.minorTickLength = 5.0f;
axisSet.xAxis.majorTickLength = 7.0f;
axisSet.yAxis.title = #"Data Y";
axisSet.yAxis.titleTextStyle = textStyle;
axisSet.yAxis.titleOffset = 40.0f;
axisSet.yAxis.axisLineStyle = lineStyle;
axisSet.yAxis.majorTickLineStyle = lineStyle;
axisSet.yAxis.minorTickLineStyle = lineStyle;
axisSet.yAxis.labelTextStyle = textStyle;
axisSet.yAxis.labelOffset = 3.0f;
axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(20.0f);
axisSet.yAxis.minorTicksPerInterval = 1;
axisSet.yAxis.minorTickLength = 5.0f;
axisSet.yAxis.majorTickLength = 7.0f;
// Add a plot to our graph and axis. We give it an identifier so that we
// could add multiple plots (data lines) to the same graph if necessary.
CPTScatterPlot *plot = [[CPTScatterPlot alloc] init];
plot.dataSource = self;
plot.identifier = #"mainplot";
plot.dataLineStyle = lineStyle;
plot.plotSymbol = plotSymbol;
[_graph reloadData];
[self.graph addPlot:plot];
}
I need to add two graphs. Is using (void)initialisePlot:(NSUIInteger)indexOfPlot a good choice? When I use this I can use only one graph at a time. Is it possible to overcome this? Two graphs on the same page and plot at the same time?
Each graph should have its own hosting view. Add both hosting views as subviews of a common parent and position them as you would any other views. Add a different graph to each hosting view.

Resources