我正在开发一个iOS应用程序,我正在使用CorePlot库(2.1版)来绘制散点图。我的散点图绘制得很好,在下一步中我想在绘图上绘制一个半透明的置信椭圆。我写了一个计算主轴和短轴以及椭圆所需旋转角度的类。我的ConfidenceEllipse类实现了一个getPath()方法,该方法返回一个表示要绘制的椭圆的CGPath。
func getPath() -> CGPath
{
var ellipse: CGPath
var transform = CGAffineTransformIdentity
transform = CGAffineTransformTranslate (transform, CGFloat(-self.meanX), CGFloat(-self.meanY))
transform = CGAffineTransformRotate (transform, CGFloat(self.angle))
transform = CGAffineTransformTranslate (transform, CGFloat(self.meanX), CGFloat(self.meanY))
ellipse = CGPathCreateWithEllipseInRect(CGRectMake (CGFloat(-self.mainHalfAxis), CGFloat(-self.minorHalfAxis), CGFloat(2 * self.mainHalfAxis), CGFloat(2 * self.minorHalfAxis)),&transform)
return ellipse
}
在网上搜索了一段时间后,看来Annotations是要走的路,所以我尝试了这个:
let graph = hostView.hostedGraph!
let space = graph.defaultPlotSpace
let ellipse = ConfidenceEllipse(chiSquare: 5.991)
ellipse.analyze(self.samples)
let annotation = CPTPlotSpaceAnnotation (plotSpace: space!, anchorPlotPoint: [0,0])
let overlay = CPTBorderedLayer (frame: graph.frame)
overlay.outerBorderPath = ellipse.getPath()
let fillColor = CPTColor.yellowColor()
overlay.fill = CPTFill (color: fillColor)
annotation.contentLayer = overlay
annotation.contentLayer?.opacity = 0.5
graph.addAnnotation(annotation)
这样做,会给我以下内容 Screenshot 正如您所看到的,叠加占用了帧的完整大小,这似乎是合乎逻辑的,因为我在创建 CPTBorderedLayer 对象时传递了帧维度。我也尝试将构造函数留空,但是叠加层根本没有显示。所以我想知道,这里有什么我想念的吗?
答案 0 :(得分:0)
您需要缩放椭圆以匹配绘图。使用绘图区域bounds
作为注记图层的框架,并将注释附加到绘图区域。在x和y方向上缩放椭圆,以匹配绘图空间使用的变换,以拟合绘图区域中的绘图。
编辑:
在研究了边界层的工作方式之后,我意识到上面的建议不会起作用。每当图层边界发生变化时,CPTBorderedLayer
会自动设置outerBorderPath
。不要试图影响图层边框,而是将椭圆绘制到图像中,并将其用作边框图层的fill
。您应该调整图层的大小,使椭圆恰好适合内部。
答案 1 :(得分:0)
在未能使Annotations正常工作之后,我决定走另一条路。我的最终解决方案是将原始散点图与第二个散点图重叠,后者仅包含一个数据点,即置信椭圆的中心。这是代码
func drawConfidenceEllipse () {
let graph = hostView.hostedGraph!
let plotSpace = graph.defaultPlotSpace as! CPTXYPlotSpace
let scaleX = (graph.bounds.size.width - graph.paddingLeft - graph.paddingRight) / CGFloat(plotSpace.xRange.lengthDouble)
let scaleY = (graph.bounds.size.height - graph.paddingTop - graph.paddingBottom) / CGFloat(plotSpace.yRange.lengthDouble)
let analysis = ConfidenceEllipse(chiSquare: 5.991)
analysis.analyze(self.samples)
let unscaledPath = analysis.getPath()
let bounds = CGPathGetBoundingBox(unscaledPath)
var scaler = CGAffineTransformIdentity
scaler = CGAffineTransformScale (scaler, scaleX, scaleY)
scaler = CGAffineTransformTranslate (scaler, CGFloat (-bounds.origin.x), CGFloat (-bounds.origin.y))
let scaledPath = CGPathCreateCopyByTransformingPath (unscaledPath, &scaler)
let scaledBounds = CGPathGetPathBoundingBox(scaledPath)
let symbol = CPTPlotSymbol ()
symbol.symbolType = CPTPlotSymbolType.Custom
symbol.customSymbolPath = scaledPath
symbol.fill = CPTFill (color: CPTColor.yellowColor().colorWithAlphaComponent(0.25))
symbol.size = CGSize (width: scaledBounds.size.width, height: scaledBounds.size.height)
let lineStyle = CPTMutableLineStyle()
lineStyle.lineWidth = 1
lineStyle.lineColor = CPTColor.yellowColor()
symbol.lineStyle = lineStyle
let ellipse = CPTScatterPlot (frame: hostView.frame)
ellipse.title = "Confidence Ellipse"
ellipse.delegate = self
ellipse.dataSource = self
ellipse.plotSymbol = symbol
ellipse.dataLineStyle = nil
graph.addPlot(ellipse)
}
以下是最终结果的屏幕截图:
95% Confidence Ellipse on top of scatter plot
希望这有帮助