Two y axis in core plot graph with different axis scales
Asked Answered
I

1

8

I am programming a app where I have graph with two y axis and one x axis.left y axis has range from 0 to 20 so there are 20 majorTick axis.Right y axis has range from 0 to 10,so I want left y axis to be labelled for every alternate majorTickAxis.

here is my code snippet

//code
   CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
float xmax=10.0;
float xmin=0.0;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xmin)      length:CPTDecimalFromFloat(xmax-xmin)];
float ymax=20.0;
float ymin=0.0;
float ymax2=10.0;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(ymin) length:CPTDecimalFromFloat(ymax-ymin)];



// Grid line styles
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.75];

CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle];
minorGridLineStyle.lineWidth = 0.25;
minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.1];

CPTMutableLineStyle *redLineStyle = [CPTMutableLineStyle lineStyle];
redLineStyle.lineWidth = 2.0;
redLineStyle.lineColor = [[CPTColor redColor] colorWithAlphaComponent:0.5];                         

CPTMutableLineStyle *greenLineStyle = [CPTMutableLineStyle lineStyle];
greenLineStyle.lineWidth = 2.0;
greenLineStyle.lineColor = [[CPTColor greenColor] colorWithAlphaComponent:0.5];     

// Axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
CPTXYAxis *x          = axisSet.xAxis;
x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
x.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:@"1"] decimalValue];
x.minorTicksPerInterval       = 4;
x.labelOffset = 3.0f;
x.title         = @"Time";
x.titleOffset   = 20.0;
x.titleLocation = CPTDecimalFromFloat((xmax+xmin)/2);
x.majorGridLineStyle= majorGridLineStyle;
x.minorGridLineStyle=minorGridLineStyle;


CPTXYAxis *y = axisSet.yAxis;
y.majorIntervalLength         = CPTDecimalFromString(@"1.0");
y.majorTickLength=2.0f;
y.minorTicksPerInterval       = 4;
y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(0.0);
y.labelExclusionRanges = [NSArray arrayWithObjects:
                          [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0.0) 
                                                       length:CPTDecimalFromInteger(0.0)],Nil];
y.majorGridLineStyle= majorGridLineStyle;
y.minorGridLineStyle=minorGridLineStyle;


CPTXYAxis *y2 = [[(CPTXYAxis *)[CPTXYAxis alloc] initWithFrame:CGRectZero] autorelease];
y2.plotSpace    =plotSpace;     
y2.orthogonalCoordinateDecimal = CPTDecimalFromFloat(xmax);
y2.majorGridLineStyle=majorGridLineStyle;
y2.minorGridLineStyle=minorGridLineStyle;
y2.minorTicksPerInterval       = 4;
y2.majorIntervalLength        = CPTDecimalFromString(@"1.0");
y2.labelOffset        = 10.0;
y2.coordinate          =CPTCoordinateY;

y2.axisLineStyle       = x.axisLineStyle;
y2.labelTextStyle              = x.labelTextStyle;
y2.labelOffset                 = -30.0f;
y2.visibleRange                = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0) length:CPTDecimalFromInteger(ymax2)];


y2.title                       = @"Temperature";
y2.titleLocation               = CPTDecimalFromInteger(5.0);
y2.titleTextStyle              =x.titleTextStyle;
y2.titleOffset                 =-45.0f;
y2.labelExclusionRanges = [NSArray arrayWithObjects:
                          [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0.0) 
                                                       length:CPTDecimalFromInteger(0.0)],Nil];


self.graph.axisSet.axes = [NSArray arrayWithObjects:x, y, y2, nil];

// Create a plot that uses the data source method for red graph
CPTScatterPlot *redPlot = [[[CPTScatterPlot alloc] init] autorelease];
redPlot.identifier = @"red Plot";;

CPTMutableLineStyle *lineStyle = [[redPlot.dataLineStyle mutableCopy] autorelease];
lineStyle.miterLimit        = 1.0f;
redPlot.dataLineStyle = redLineStyle;
redPlot.dataSource = self;
redPlot.interpolation = CPTScatterPlotInterpolationStepped;

[self.graph addPlot:redPlot];

// Create a plot that uses the data source method for green graph
CPTScatterPlot *greenPlot = [[[CPTScatterPlot alloc] init] autorelease];
greenPlot.identifier = @"green Plot";;

CPTMutableLineStyle *greenlineStyle = [[greenPlot.dataLineStyle mutableCopy] autorelease];
greenlineStyle.miterLimit       = 1.0f;
greenPlot.dataLineStyle = greenLineStyle;
greenPlot.dataSource = self;
[self.graph addPlot:greenPlot];

 // Add some data
NSMutableArray *newData = [NSMutableArray arrayWithCapacity:100];
NSUInteger i;
for ( i = 0; i < 45; i++ ) {
    id x = [NSNumber numberWithDouble:i * 0.2];
    id y = [NSNumber numberWithDouble:i * rand() / ((double)RAND_MAX*5.0) ];        
    [newData addObject:[NSDictionary dictionaryWithObjectsAndKeys:
      x, @"x",y, @"y",nil]];
}
NSMutableArray *newData1 = [NSMutableArray arrayWithCapacity:100];
for ( i = 0; i < 45; i++ ) {
    id x =[NSNumber numberWithDouble:i * rand() / ((double)RAND_MAX*5.0) ]; 
    id y2 = [NSNumber numberWithDouble:i * 0.2];
    [newData1 addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                        x, @"x",y2, @"y2",nil]];
}
self.plotData = newData;
self.plotData2=newData1;
Illdefined answered 7/6, 2012 at 10:46 Comment(1)
Set the labelExclusionRanges to nil if you don't need it.Pubis
P
10

If you want the two y-axes to have different scales, you need to add another plot space. Use the same xRange for the second plot space, but use a different yRange, e.g.,

CPTXYPlotSpace *plotSpace2 = [[[CPTXYPlotSpace alloc] init] autorelease];
plotSpace2.xRange = plotSpace.xRange;
plotSpace2.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(ymin)
                                                 length:CPTDecimalFromFloat(ymax2 - ymin)];
[graph addPlotSpace:plotSpace2];
y2.plotSpace = plotSpace2;

Use the majorIntervalLength to control the location of the ticks and grid lines:

y.majorIntervalLength = CPTDecimalFromFloat((ymax - ymin) / 10.0f);
y2.majorIntervalLength = CPTDecimalFromFloat((ymax2 - ymin) / 10.0f);
Pubis answered 8/6, 2012 at 1:39 Comment(3)
hi Eric,Thanks a lot,your code was very helpful,Now i have different scales for both y axisIlldefined
in case i use bars for displaying my values and i have two y axes with two plot spaces (where one is red and is green for example) and they use same x-axis, that will render them over each other so for example my red bar representing first value will be covered with green representing 2nd value at the same x-axis position. I would actually like those red and green bars to be kinda centered around x-axis value so they are both visible. Is that possible?Furfuran
You can use the barOffset property to move the bars in one or both plots away from the normal center line so you can see both of them.Pubis

© 2022 - 2024 — McMap. All rights reserved.