Hey everyone!

It’s been a long time since I last posted. Since then I’ve passed the second evaluation, and am pretty close to the end of this years’s GSoC. The final evaluation period starts tomorrow.

This post will be a very brief account of the developments since the last time, and the future plans.

The first topic to address is how we plan to handle data other than Float. After some discussion it was decided that using Generics would be a good option. I wrote a FloatConvertible protocol, and wrote Float and Double extensions conforming to it. The protocol is as shown below:

public protocol FloatConvertible : Comparable{
  init<T: FloatConvertible>(_ x: T)
  init(_ other: Float)
  init(_ other: Double)
  init(_ other: Int)

  func toFloat() -> Float
  func toDouble() -> Double
  func toInt() -> Int
  static func +(lhs: Self, rhs: Self) -> Self
  static func -(lhs: Self, rhs: Self) -> Self
  static func *(lhs: Self, rhs: Self) -> Self
  static func /(lhs: Self, rhs: Self) -> Self
}

extension Float: FloatConvertible {
  public init<T: FloatConvertible>(_ x: T) {self = x.toFloat()}
  public func toFloat() -> Float {return Float(self)}
  public func toDouble() -> Double {return Double(self)}
  public func toInt() -> Int {return Int(self)}
}

extension Double: FloatConvertible {
 public init<T: FloatConvertible>(_ x: T) {self = x.toDouble()}
 public func toFloat() -> Float {return Float(self)}
 public func toDouble() -> Double {return Double(self)}
 public func toInt() -> Int {return Int(self)}
}

Now, each plot class would have generics accepting values conforming to the FloatConvertible protocol. I’m using Floats for calculations at most places. As the input data conforms to FloatConvertible we can convert each value to a Float before any operation. This method also avoids type erasure. Most of you might notice that there’s no extension for the Int data type. That’s because I’m facing some issues with it. Whenever I use Integers I get a fatal error while execution, the reason to which I haven’t been able to figure out yet. So, currently we can use Float and Double.

The next issue I came across was when I was testing plotting different values. I had forgotten to consider a case when the range of values was less than 1, i.e. the plot markers had to have decimal values. So what I did was if the range was between 1 and 2, I plotted each marker with an increment of half times the inverse of the range. And when the range was less than 1, each increment was one-tenth of the range. I also rounded the values to two significant digits. This worked well for most cases.

Brad pointed out that the current plots weren’t as aesthetically pleasing as those generated by currently existing frameworks. The following needed to be changed:

1. Font

2. Line Size

3. Spacing of numbers from axis hatching

4. Enable a grid

Changing the line size, spacing and enabling a grid were simple tasks and didn’t take a lot of time. The tricky part was using a custom font. Let’s take a look at the approach used with both AGG and SVG Renderers.

AGG provides a way to draw text using custom fonts using the FreeType library. Either we need to include FreeType with SwiftPlot or we need a way so that Swift Package Manager can use a version of FreeType installed on the device. I initially wanted to include FreeType with SwiftPlot, but FreeType has its own build system and it also had a few Python files in its source. So I ruled that out. In order to use the install on the device I needed a module that lets SPM know which library to look for. I found this C module on github which with a few changes I got working. Then I changed the old text functions to use the FreeType functions provided by AGG. The default font I used was Roboto-Regular. I had two reasons for choosing this font. One, it was very clean and professional looking. Second, this font was available in the Google Fonts API(This came in useful for SVG).

I couldn’t find any simple way to use custom fonts in SVG that worked everywhere. The only method I found was to use CSS, which worked only in a browser. Brad said that people would use SVG primarily in a browser so supporting that could be a good beginning. The next problem was how to set a default font in SVG? We couldn’t include the font in the SVG file, and including the ttf file along with the SVG file would be very inconvenient. Here the Google Fonts API came in useful. We just need to specify the font family and it would fetch the font whenever the image was loaded into the browser.

This almost concludes my work on aesthetics. The only problem left is to get FreeType to work with Jupyter. Currently, It isn’t able to find the FreeType installed on the system.

Histogram with updated font and grid

Apart from this my main objectives are complete. In the leftover time I have started work on a CoreGraphics Renderer for macOS. This would be a great addition to the library and increase its audience.

That’s all for this post. I’ll post an update when I have CoreGraphics working. Stay tuned!