Skip to content

Commit f9ea3b6

Browse files
committed
Added heatmap slicing convenience for generating a heatmap with a particular height
1 parent a8e00dc commit f9ea3b6

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

Sources/SwiftPlot/Heatmap.swift

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,31 @@ extension RandomAccessCollection {
173173
public func heatmap(width: Int, interpolator: Interpolator<Element>) -> Heatmap<[SubSequence]> {
174174
precondition(width > 0, "Cannot build a histogram with zero or negative width")
175175
let height = Int((Float(count) / Float(width)).rounded(.up))
176-
return (0..<height).map { row -> SubSequence in
177-
guard let start = index(startIndex, offsetBy: row * width, limitedBy: endIndex) else {
178-
return self[startIndex..<startIndex]
179-
}
180-
guard let end = index(start, offsetBy: width, limitedBy: endIndex) else {
181-
return self[start..<endIndex]
182-
}
183-
return self[start..<end]
184-
}.heatmap(interpolator: interpolator)
176+
return (0..<height)
177+
.map { _sliceForRow($0, width: width) }
178+
.heatmap(interpolator: interpolator)
179+
}
180+
181+
/// Returns a heatmap of this collection's values, generated by the data in to `height` rows.
182+
/// - parameters:
183+
/// - height: The height of the heatmap to generate. Must be greater than 0.
184+
/// - interpolator: A function or `KeyPath` which maps values to a continuum between 0 and 1.
185+
/// - returns: A heatmap plot of the collection's values.
186+
public func heatmap(height: Int, interpolator: Interpolator<Element>) -> Heatmap<[SubSequence]> {
187+
precondition(height > 0, "Cannot build a histogram with zero or negative height")
188+
let width = Int((Float(count) / Float(height)).rounded(.up))
189+
return (0..<height)
190+
.map { _sliceForRow($0, width: width) }
191+
.heatmap(interpolator: interpolator)
192+
}
193+
194+
private func _sliceForRow(_ row: Int, width: Int) -> SubSequence {
195+
guard let start = index(startIndex, offsetBy: row * width, limitedBy: endIndex) else {
196+
return self[startIndex..<startIndex]
197+
}
198+
guard let end = index(start, offsetBy: width, limitedBy: endIndex) else {
199+
return self[start..<endIndex]
200+
}
201+
return self[start..<end]
185202
}
186203
}

Tests/SwiftPlotTests/Heatmap/heatmap.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ final class HeatmapTests: SwiftPlotTestCase {
3030

3131
var d = Data(capacity: 10_000)
3232
for _ in 0..<10_000 { d.append(.random(in: 0..<255)) }
33-
var hm3 = d.heatmap(width: 100, interpolator: .linear)
33+
// var hm3 = d.heatmap(width: 100, interpolator: .linear)
3434

35-
// var hm3 = Array("THIS IS SWIFPLOT!!!! Woo let's see what this looks like :)")
36-
// .heatmap(width: 5, interpolator: .linearByKeyPath(\.asciiValue!))
35+
var hm3 = Array("THIS IS SWIFPLOT!!!! Woo let's see what this looks like :)")
36+
.heatmap(height: 1, interpolator: .linearByKeyPath(\.asciiValue!))
3737
// var hm3 = Array(stride(from: Float(0), to: 1, by: 0.001)).heatmap(width: 10, interpolator: .linear)
3838
hm3.colorMap = .viridis
3939

0 commit comments

Comments
 (0)