Skip to content

Commit

Permalink
- add plot compatibility with go-chart pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
rocketlaunchr-cto committed Apr 12, 2020
1 parent 031f88c commit 5edbfa6
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 0 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,32 @@ median, _ := stats.Median(sf.Values)
std := stat.StdDev(sf.Values, nil)
```

## Plotting (only Windows, macOS and Linux)

```go
import (
"github.com/rocketlaunchr/dataframe-go/plot"
c "github.com/rocketlaunchr/dataframe-go/plot/wcharczuk/go-chart"
)

sales := dataframe.NewSeriesFloat64("sales", nil, 50.3, nil, 23.4, 56.2, 89, 32, 84.2, 72, 89)
cs, _ := c.S(ctx, sales, nil)

graph := chart.Chart{Series: []chart.Series{cs}}

plt, _ := plot.Open("Monthly sales", 450, 300)
graph.Render(chart.SVG, plt)
plt.Display(plot.SVG)
<-plt.Closed

```

Output:

<p align="center">
<img src="https://github.com/rocketlaunchr/dataframe-go/raw/master/plot.png" alt="plot" />
</p>

## Importing Data

The `imports` sub-package has support for importing csv, jsonl and directly from a SQL database. The `DictateDataType` option can be set to specify the true underlying data type. Alternatively, `InferDataTypes` option can be set.
Expand Down
15 changes: 15 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ func B(b bool) int {
return 0
}

// IsValidFloat64 returns true if f is neither Nan nor ±Inf.
// Otherwise it returns false.
func IsValidFloat64(f float64) bool {

if isNaN(f) {
return false
}

if isInf(f, 0) {
return false
}

return true
}

// BoolValueFormatter is used by SetValueToStringFormatter
// to display an int as a bool. If the encountered value
// is not a 0 or 1, it will panic.
Expand Down
Binary file added plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions plot/plot.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2018-20 PJ Engineering and Business Solutions Pty. Ltd. All rights reserved.

package plot

import (
Expand Down
107 changes: 107 additions & 0 deletions plot/wcharczuk/go-chart/chart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2018-20 PJ Engineering and Business Solutions Pty. Ltd. All rights reserved.

package chart

import (
"context"
"time"

"github.com/wcharczuk/go-chart"

dataframe "github.com/rocketlaunchr/dataframe-go"
)

// S converts a SeriesFloat64 to a chart.Series for usage with the "github.com/wcharczuk/go-chart" package.
// Currently x can be nil, a SeriesFloat64 or a SeriesTime. nil values in the x and y Series are ignored.
func S(ctx context.Context, y *dataframe.SeriesFloat64, x interface{}, r ...dataframe.Range) (chart.Series, error) {

var out chart.Series

if len(r) == 0 {
r = append(r, dataframe.Range{})
}

yNRows := y.NRows(dataframe.DontLock)

start, end, err := r[0].Limits(yNRows)
if err != nil {
return nil, err
}

switch xx := x.(type) {
case nil:
cs := chart.ContinuousSeries{Name: y.Name(dataframe.DontLock)}

xVals := []float64{}
yVals := []float64{}

// Remove nil values
for i, j := 0, start; j < end+1; i, j = i+1, j+1 {
yval := y.Values[j]

if dataframe.IsValidFloat64(yval) {
yVals = append(yVals, yval)
xVals = append(xVals, float64(i))
}
}

cs.XValues = xVals
cs.YValues = yVals

out = cs
case *dataframe.SeriesFloat64:

cs := chart.ContinuousSeries{Name: y.Name(dataframe.DontLock)}

xVals := []float64{}
yVals := []float64{}

// Remove nil values
for i, j := 0, start; j < end+1; i, j = i+1, j+1 {
yval := y.Values[j]
xval := xx.Values[j]

if dataframe.IsValidFloat64(yval) {
// Check x val is valid
if dataframe.IsValidFloat64(xval) {
yVals = append(yVals, yval)
xVals = append(xVals, xval)
}
}
}

cs.XValues = xVals
cs.YValues = yVals

out = cs
case *dataframe.SeriesTime:

cs := chart.TimeSeries{Name: y.Name(dataframe.DontLock)}

xVals := []time.Time{}
yVals := []float64{}

// Remove nil values
for i, j := 0, start; j < end+1; i, j = i+1, j+1 {
yval := y.Values[j]
xval := xx.Values[j]

if dataframe.IsValidFloat64(yval) {
// Check x val is valid
if xval != nil {
yVals = append(yVals, yval)
xVals = append(xVals, *xval)
}
}
}

cs.XValues = xVals
cs.YValues = yVals

out = cs
default:
panic("unrecognized x")
}

return out, nil
}

0 comments on commit 5edbfa6

Please sign in to comment.