I'm trying to plot a histogram. The x-axis range should be about 881 to 1281 (I've verified that I'm using a location of 881 and range of 400 when constructing the CPTPlotRange for xRange). The axis draws with the correct range, but my bars end up near 2000 (data space), even though my data source method is sending location values between 881 and 1281.
Here's the code:
- (void)
viewDidLoad
{
[super viewDidLoad];
InputVariable temp(1081.0, 50.0);
self.hist = new Histogram(temp.mean(), temp.stdDev(), 5.0);
for (Histogram::SizeT i = 0; i < 1000; ++i)
{
double v = temp.randomValue();
self.hist->add(v);
}
const Histogram& hist = *self.hist;
CPTXYGraph* graph = [[CPTXYGraph alloc] initWithFrame: self.chart1.bounds];
graph.fill = [CPTFill fillWithColor: [CPTColor lightGrayColor]];
graph.cornerRadius = 4.0;
self.chart1.hostedGraph = graph;
self.graph = graph;
// Plot area
graph.plotAreaFrame.fill = [CPTFill fillWithColor:[CPTColor lightGrayColor]];
graph.plotAreaFrame.paddingTop = 4.0;
graph.plotAreaFrame.paddingBottom = 50.0;
graph.plotAreaFrame.paddingLeft = 50.0;
graph.plotAreaFrame.paddingRight = 4.0;
graph.plotAreaFrame.cornerRadius = 4.0;
graph.plotAreaFrame.masksToBorder = NO;
graph.plotAreaFrame.axisSet.borderLineStyle = [CPTLineStyle lineStyle];
graph.plotAreaFrame.plotArea.fill = [CPTFill fillWithColor:[CPTColor whiteColor]];
// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(hist.lowValue()) length:CPTDecimalFromDouble(hist.range())];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(hist.maxBinCount() * 1.2)];
//plotSpace.yScaleType = CPTScaleTypeLog;
// Line styles
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0;
//axisLineStyle.lineCap = kCGLineCapRound;
CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 0.75;
majorGridLineStyle.lineColor = [CPTColor redColor];
CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle];
minorGridLineStyle.lineWidth = 0.25;
minorGridLineStyle.lineColor = [CPTColor blueColor];
// Text styles
CPTMutableTextStyle *axisTitleTextStyle = [CPTMutableTextStyle textStyle];
axisTitleTextStyle.fontName = @"Helvetica Neue Bold";
axisTitleTextStyle.fontSize = 14.0;
// Axes
// Label x axis with a fixed interval policy
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.separateLayers = NO;
x.orthogonalCoordinateDecimal = CPTDecimalFromDouble(0.0);
x.majorIntervalLength = CPTDecimalFromDouble(0.5);
x.minorTicksPerInterval = 4;
x.tickDirection = CPTSignNone;
x.axisLineStyle = axisLineStyle;
x.majorTickLength = 12.0;
x.majorTickLineStyle = axisLineStyle;
//x.majorGridLineStyle = majorGridLineStyle;
x.minorTickLength = 8.0;
//x.minorGridLineStyle = minorGridLineStyle;
x.title = @"Temperature";
x.titleTextStyle = axisTitleTextStyle;
x.titleOffset = 25.0;
//x.alternatingBandFills = @[[[CPTColor redColor] colorWithAlphaComponent:0.1], [[CPTColor greenColor] colorWithAlphaComponent:0.1]];
x.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
// Label y with an automatic label policy.
//axisLineStyle.lineColor = [CPTColor greenColor];
CPTXYAxis *y = axisSet.yAxis;
y.separateLayers = YES;
y.orthogonalCoordinateDecimal = plotSpace.xRange.location;//CPTDecimalFromDouble(hist.lowValue());
y.minorTicksPerInterval = 9;
y.tickDirection = CPTSignNone;
y.axisLineStyle = axisLineStyle;
y.majorTickLength = 12.0;
y.majorTickLineStyle = axisLineStyle;
//y.majorGridLineStyle = majorGridLineStyle;
//y.minorTickLength = 8.0;
//y.minorGridLineStyle = minorGridLineStyle;
y.title = @"Number of Samples";
y.titleTextStyle = axisTitleTextStyle;
y.titleOffset = 40.0;
//y.alternatingBandFills = @[[[CPTColor blueColor] colorWithAlphaComponent:0.1], [NSNull null]];
y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
//CPTFill *bandFill = [CPTFill fillWithColor:[[CPTColor darkGrayColor] colorWithAlphaComponent:0.5]];
//[y addBackgroundLimitBand:[CPTLimitBand limitBandWithRange:[CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(7.0) length:CPTDecimalFromDouble(1.5)] fill:bandFill]];
//[y addBackgroundLimitBand:[CPTLimitBand limitBandWithRange:[CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(1.5) length:CPTDecimalFromDouble(3.0)] fill:bandFill]];
// Set up the bar plot…
//CPTXYPlotSpace *barPlotSpace = [[CPTXYPlotSpace alloc] init];
CPTXYPlotSpace *barPlotSpace = (CPTXYPlotSpace *) self.graph.defaultPlotSpace;
//barPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(200.0)];
//barPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(15.00)];
//[self.graph addPlotSpace:barPlotSpace];
CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor darkGrayColor] horizontalBars: false];
barPlot.dataSource = self;
barPlot.barsAreHorizontal = false;
barPlot.barWidth = CPTDecimalFromDouble(1.0);
barPlot.barBasesVary = false;
barPlot.baseValue = CPTDecimalFromDouble(0.0);
barPlot.barOffset = CPTDecimalFromDouble(hist.lowValue());
barPlot.identifier = @"Bar Plot";
//barPlot.plotRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(7.0)];
CPTMutableTextStyle *whiteTextStyle = [CPTMutableTextStyle textStyle];
whiteTextStyle.color = [CPTColor whiteColor];
//barPlot.labelTextStyle = whiteTextStyle;
[self.graph addPlot:barPlot toPlotSpace:barPlotSpace];
}
- (NSUInteger)
numberOfRecordsForPlot: (CPTPlot*) inPlot
{
return self.hist->numBins();
}
- (double)
doubleForPlot: (CPTPlot*) inPlot
field: (NSUInteger) inField
recordIndex: (NSUInteger) inIdx
{
const Histogram& h = *self.hist;
if (inField == CPTBarPlotFieldBarLocation)
{
double v = h.binMid(inIdx);
NSLog(@"v: %f", v);
return v;
}
else if (inField == CPTBarPlotFieldBarTip)
{
return h[inIdx];
}
return 0.0;
}
And the resulting graph:
Any idea what I'm doing wrong? Thanks!
For this application, the barOffset
should be zero (0). The offset is used to displace the bars from the location given by the datasource. The most common use is to separate the bars at the same location when plotting multiple bar plots on the same graph that might have overlapping bars at common locations.