Multiple scatterplots using Core Plot and Swift

醉酒当歌 提交于 2019-12-11 02:26:25

问题


I'm trying to find a way to add two different scatterplots to a single graph but i wasn't able so far. I've found some examples in Objective-C but nothing in Swift, just the Scatterplot example in the CorePlot 2.1 release, but it plots the same data in two different line colors.

This is what i have so far (only one scatter plot is plotted):

import UIKit
import CorePlot

class ViewController : UIViewController, CPTScatterPlotDataSource {
    private var scatterGraph : CPTXYGraph? = nil

typealias plotDataType = [CPTScatterPlotField : Double]
private var dataForPlot = [plotDataType]()
@IBOutlet var graphView: UIView!

// MARK: Initialization

override func viewDidAppear(animated : Bool)
{
    super.viewDidAppear(animated)

    // Create graph from theme
    let newGraph = CPTXYGraph(frame: CGRectZero)
    newGraph.applyTheme(CPTTheme(named: kCPTDarkGradientTheme))

    let hostingView = graphView as! CPTGraphHostingView
    hostingView.hostedGraph = newGraph

    // Paddings
    newGraph.paddingLeft   = 10.0
    newGraph.paddingRight  = 10.0
    newGraph.paddingTop    = 10.0
    newGraph.paddingBottom = 10.0

    // Plot space
    let plotSpace = newGraph.defaultPlotSpace as! CPTXYPlotSpace
    //plotSpace.allowsUserInteraction = true
    plotSpace.yRange = CPTPlotRange(location:0, length:10)
    plotSpace.xRange = CPTPlotRange(location:0, length:10)

    // Axes
    let axisSet = newGraph.axisSet as! CPTXYAxisSet

    if let x = axisSet.xAxis {
        x.majorIntervalLength   = 2
        x.orthogonalPosition    = 2.0
        x.minorTicksPerInterval = 2

    }

    if let y = axisSet.xAxis {
        y.majorIntervalLength   = 2
        y.minorTicksPerInterval = 5
        y.orthogonalPosition    = 2.0

        y.delegate = self
    }

    // Create a blue plot area
    let boundLinePlot = CPTScatterPlot(frame: CGRectZero)
    let blueLineStyle = CPTMutableLineStyle()
    blueLineStyle.miterLimit    = 1.0
    blueLineStyle.lineWidth     = 3.0
    blueLineStyle.lineColor     = CPTColor.blueColor()
    boundLinePlot.dataLineStyle = blueLineStyle

    boundLinePlot.identifier    = "Blue Plot"
    boundLinePlot.dataSource    = self
    newGraph.addPlot(boundLinePlot)

    // Add plot symbols
    let symbolLineStyle = CPTMutableLineStyle()
    symbolLineStyle.lineColor = CPTColor.blackColor()
    let plotSymbol = CPTPlotSymbol.ellipsePlotSymbol()
    plotSymbol.fill          = CPTFill(color: CPTColor.blueColor())
    plotSymbol.lineStyle     = symbolLineStyle
    plotSymbol.size          = CGSize(width: 10.0, height: 10.0)

    // Put an area gradient under the plot above
    let areaColor    = CPTColor(componentRed: 0.3, green: 1.0, blue: 0.3, alpha: 0.8)
    let areaGradient = CPTGradient(beginningColor: areaColor, endingColor: CPTColor.clearColor())
    areaGradient.angle = -90.0
    let areaGradientFill = CPTFill(gradient: areaGradient)

    // Add some initial data
    var contentArray = [plotDataType]()

    let plotData1: plotDataType = [.X: 0, .Y: 5]
    let plotData2: plotDataType = [.X: 5, .Y: 0]
    contentArray.append(plotData1)
    contentArray.append(plotData2)
    self.dataForPlot = contentArray

    self.scatterGraph = newGraph


}

// MARK: - Plot Data Source Methods

func numberOfRecordsForPlot(plot: CPTPlot) -> UInt
{
    return UInt(self.dataForPlot.count)
}

func numberForPlot(plot: CPTPlot, field: UInt, recordIndex: UInt) -> AnyObject?
{
    let plotField = CPTScatterPlotField(rawValue: Int(field))

    if let num = self.dataForPlot[Int(recordIndex)][plotField!] {

            return num as NSNumber

    }
    else {
        return nil
    }
}

// MARK: - Axis Delegate Methods

func axis(axis: CPTAxis, shouldUpdateAxisLabelsAtLocations locations: NSSet!) -> Bool
{
    if let formatter = axis.labelFormatter {
        let labelOffset = axis.labelOffset

        var newLabels = Set<CPTAxisLabel>()

        for tickLocation in locations {
            if let labelTextStyle = axis.labelTextStyle?.mutableCopy() as? CPTMutableTextStyle {

                if tickLocation.doubleValue >= 0.0 {
                    labelTextStyle.color = CPTColor.greenColor()
                }
                else {
                    labelTextStyle.color = CPTColor.redColor()
                }

                let labelString   = formatter.stringForObjectValue(tickLocation)
                let newLabelLayer = CPTTextLayer(text: labelString, style: labelTextStyle)

                let newLabel = CPTAxisLabel(contentLayer: newLabelLayer)
                newLabel.tickLocation = tickLocation as! NSNumber
                newLabel.offset       = labelOffset

                newLabels.insert(newLabel)
            }

            axis.axisLabels = newLabels
        }
    }

    return false
}
}

This gives me a single line, but i want to add an additional line with a different data.

Any suggestions?


回答1:


For a starter, create two CPTScatterPlots (e.g. boundLinePlot1 & boundLinePlot2)and configure them with different colors and different identifier then add them

boundLinePlot1.identifier = "Blue Plot"
boundLinePlot2.identifier = "Green Plot"

newGraph.addPlot(boundLinePlot1) 
newGraph.addPlot(boundLinePlot2)

Now in the Plot Data Source Methods (numberOfRecordsForPlot & numberForPlot) calculate return value based on plot.identifier

if plot.identifier == "Blue Plot" {
    return dataForPlot1[Int(recordIndex)][plotField!]
} else {
    return dataForPlot2[Int(recordIndex)][plotField!]
}


来源:https://stackoverflow.com/questions/39012291/multiple-scatterplots-using-core-plot-and-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!