Documentation
¶
Overview ¶
Package plot provides live plotting drawers for window.Window, using the gonum/plot package or direct OpenGL drawing.
For the window, see package github.com/mlange-42/ark-pixel/window.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Bars ¶
type Bars struct {
Observer observer.Row // Observer providing a data series for bars.
Columns []string // Columns to show, by name. Optional, default all.
YLim [2]float64 // Y axis limits. Optional, default auto.
Labels Labels // Labels for plot and axes. Optional.
// contains filtered or unexported fields
}
Bars plot drawer.
Creates a bar per column of the observer.
Example ¶
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
// Create a time series plot.
app.AddUISystem((&window.Window{}).
With(&plot.Bars{
Observer: &RowObserver{},
YLim: [...]float64{0, 4}, // Optional Y axis limits.
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
func (*Bars) Initialize ¶
Initialize the drawer.
type Contour ¶
type Contour struct {
Observer observer.Grid // Observers providing a Grid for contours.
Levels []float64 // Levels for iso lines. Optional.
Palette palette.Palette // Color palette. Optional.
Labels Labels // Labels for plot and axes. Optional.
HideLegend bool // Hides the legend.
// contains filtered or unexported fields
}
Contour plot drawer.
Plots a grid as a contours. For large grids, this is relatively slow. Consider using Image instead.
Example ¶
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
app.FPS = 0
// Create a contour plot.
app.AddUISystem(
(&window.Window{}).
With(&plot.Contour{
Observer: observer.MatrixToGrid(&MatrixObserver{}, nil, nil),
Palette: palette.Heat(16, 1),
Levels: []float64{-2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2},
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
func (*Contour) Initialize ¶
Initialize the drawer.
type Field ¶
type Field struct {
Observer observer.GridLayers // Observers providing field component grids.
Labels Labels // Labels for plot and axes. Optional.
Layers []int // Layer indices. Optional, defaults to (0, 1).
// contains filtered or unexported fields
}
Field plot drawer.
Plots a vector field from a GridLayers observer. For large grids, this is relatively slow. Consider using ImageRGB instead.
Example ¶
package main
import (
"math"
"github.com/mlange-42/ark-pixel/plot"
"github.com/mlange-42/ark-pixel/window"
"github.com/mlange-42/ark-tools/app"
"github.com/mlange-42/ark-tools/observer"
"github.com/mlange-42/ark-tools/system"
"github.com/mlange-42/ark/ecs"
)
func main() {
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
app.FPS = 0
// Create a contour plot.
app.AddUISystem(
(&window.Window{}).
With(&plot.Field{
Observer: observer.LayersToLayers(&FieldObserver{}, nil, nil),
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
}
type FieldObserver struct {
cols int
rows int
values [][]float64
}
func (o *FieldObserver) Initialize(w *ecs.World) {
o.cols = 60
o.rows = 40
o.values = make([][]float64, 2)
for i := 0; i < len(o.values); i++ {
o.values[i] = make([]float64, o.cols*o.rows)
}
}
func (o *FieldObserver) Update(w *ecs.World) {}
func (o *FieldObserver) Dims() (int, int) {
return o.cols, o.rows
}
func (o *FieldObserver) Layers() int {
return 2
}
func (o *FieldObserver) Values(w *ecs.World) [][]float64 {
ln := len(o.values[0])
for idx := range ln {
i := idx % o.cols
j := idx / o.cols
o.values[0][idx] = math.Sin(float64(i))
o.values[1][idx] = -math.Sin(float64(j))
}
return o.values
}
Output:
func (*Field) Initialize ¶
Initialize the drawer.
type HeatMap ¶
type HeatMap struct {
Observer observer.Grid // Observers providing a Grid for contours.
Palette palette.Palette // Color palette. Optional.
Min float64 // Minimum value for color mapping. Optional.
Max float64 // Maximum value for color mapping. Optional. Is set to 1.0 if both Min and Max are zero.
Labels Labels // Labels for plot and axes. Optional.
// contains filtered or unexported fields
}
HeatMap plot drawer.
Plots a grid as a heatmap image. For large grids, this is relatively slow. Consider using Image instead.
Example ¶
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
app.FPS = 0
// Create a contour plot.
app.AddUISystem(
(&window.Window{}).
With(&plot.HeatMap{
Observer: observer.MatrixToGrid(&MatrixObserver{}, nil, nil),
Palette: palette.Heat(16, 1),
Min: -2,
Max: 2,
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
func (*HeatMap) Initialize ¶
Initialize the drawer.
type Image ¶
type Image struct {
Scale float64 // Spatial scaling: cell size in screen pixels. Optional, default auto.
Observer observer.Matrix // Observer providing 2D matrix or grid data.
Colors colorgrad.Gradient // Colors for mapping values.
Min float64 // Minimum value for color mapping. Optional.
Max float64 // Maximum value for color mapping. Optional. Is set to 1.0 if both Min and Max are zero.
// contains filtered or unexported fields
}
Image drawer.
Draws an image from a Matrix observer. The image is scaled to the canvas extent, with preserved aspect ratio. Does not add plot axes etc.
Example ¶
package main
import (
"math"
"github.com/mazznoer/colorgrad"
"github.com/mlange-42/ark-pixel/plot"
"github.com/mlange-42/ark-pixel/window"
"github.com/mlange-42/ark-tools/app"
"github.com/mlange-42/ark-tools/system"
"github.com/mlange-42/ark/ecs"
)
func main() {
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
app.FPS = 0
// Create an image plot.
// See below for the implementation of the MatrixObserver.
app.AddUISystem(
(&window.Window{}).
With(&plot.Image{
Scale: 4,
Observer: &MatrixObserver{},
Colors: colorgrad.Inferno(),
Min: -2,
Max: 2,
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
}
// Example observer, reporting a matrix with z = sin(0.1*i) + sin(0.2*j).
type MatrixObserver struct {
cols int
rows int
values []float64
}
func (o *MatrixObserver) Initialize(w *ecs.World) {
o.cols = 160
o.rows = 120
o.values = make([]float64, o.cols*o.rows)
}
func (o *MatrixObserver) Update(w *ecs.World) {}
func (o *MatrixObserver) Dims() (int, int) {
return o.cols, o.rows
}
func (o *MatrixObserver) Values(w *ecs.World) []float64 {
for idx := 0; idx < len(o.values); idx++ {
i := idx % o.cols
j := idx / o.cols
o.values[idx] = math.Sin(0.1*float64(i)) + math.Sin(0.2*float64(j))
}
return o.values
}
Output:
func (*Image) Initialize ¶
Initialize the system
type ImageRGB ¶
type ImageRGB struct {
Scale float64 // Spatial scaling: cell size in screen pixels. Optional, default auto.
Observer observer.MatrixLayers // Observer providing data for color channels.
Layers []int // Layer indices. Optional, defaults to [0, 1, 2]. Use -1 to ignore a channel.
Min []float64 // Minimum value for channel color mapping. Optional, default [0, 0, 0].
Max []float64 // Maximum value for channel color mapping. Optional, default [1, 1, 1].
// contains filtered or unexported fields
}
ImageRGB drawer.
Draws an image from a Matrix observer per RGB color channel. The image is scaled to the canvas extent, with preserved aspect ratio. Does not add plot axes etc.
Example ¶
package main
import (
"math"
"github.com/mlange-42/ark-pixel/plot"
"github.com/mlange-42/ark-pixel/window"
"github.com/mlange-42/ark-tools/app"
"github.com/mlange-42/ark-tools/observer"
"github.com/mlange-42/ark-tools/system"
"github.com/mlange-42/ark/ecs"
)
func main() {
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
// Create an RGB image plot.
// See below for the implementation of the CallbackMatrixObserver.
app.AddUISystem((&window.Window{}).
With(&plot.ImageRGB{
Observer: observer.MatrixToLayers(
&CallbackMatrixObserver{Callback: func(i, j int) float64 { return float64(i) / 240 }},
&CallbackMatrixObserver{Callback: func(i, j int) float64 { return math.Sin(0.1 * float64(i)) }},
&CallbackMatrixObserver{Callback: func(i, j int) float64 { return float64(j) / 160 }},
),
Min: []float64{0, 0, 0},
Max: []float64{1, 1, 1},
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
}
// Example observer, reporting a matrix filled with a callback(i, j).
type CallbackMatrixObserver struct {
Callback func(i, j int) float64
cols int
rows int
values []float64
}
func (o *CallbackMatrixObserver) Initialize(w *ecs.World) {
o.cols = 240
o.rows = 160
o.values = make([]float64, o.cols*o.rows)
}
func (o *CallbackMatrixObserver) Update(w *ecs.World) {}
func (o *CallbackMatrixObserver) Dims() (int, int) {
return o.cols, o.rows
}
func (o *CallbackMatrixObserver) Values(w *ecs.World) []float64 {
for idx := 0; idx < len(o.values); idx++ {
i := idx % o.cols
j := idx / o.cols
o.values[idx] = o.Callback(i, j)
}
return o.values
}
Output:
func (*ImageRGB) Initialize ¶
Initialize the drawer.
type Labels ¶
Labels for plots.
Example ¶
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
// Create a time series plot, wit labels.
app.AddUISystem((&window.Window{}).
With(&plot.TimeSeries{
Observer: &RowObserver{},
Labels: plot.Labels{
Title: "Plot example",
X: "X axis label",
Y: "Y axis label",
},
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
type Lines ¶
type Lines struct {
Observer observer.Table // Observer providing a data series for lines.
X string // X column name. Optional. Defaults to row index.
Y []string // Y column names. Optional. Defaults to all but X column.
XLim [2]float64 // X axis limits. Optional, default auto.
YLim [2]float64 // Y axis limits. Optional, default auto.
Labels Labels // Labels for plot and axes. Optional.
// contains filtered or unexported fields
}
Lines plot drawer.
Creates a line series per column of the observer. Replaces the complete data by the table provided by the observer on every update. Particularly useful for live histograms.
Example ¶
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
// Create a line plot.
// See below for the implementation of the TableObserver.
app.AddUISystem((&window.Window{}).
With(&plot.Lines{
Observer: &TableObserver{},
X: "X", // Optional, defaults to row index
Y: []string{"A", "B", "C"}, // Optional, defaults to all but X
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
// window.Run(app)
func (*Lines) Initialize ¶
Initialize the drawer.
type Scatter ¶
type Scatter struct {
Observers []observer.Table // Observers providing XY data series.
X []string // X column name per observer. Optional. Defaults to first column. Empty strings also falls back to the default.
Y [][]string // Y column names per observer. Optional. Defaults to second column. Empty strings also falls back to the default.
XLim [2]float64 // X axis limits. Optional, default auto.
YLim [2]float64 // Y axis limits. Optional, default auto.
Labels Labels // Labels for plot and axes. Optional.
// contains filtered or unexported fields
}
Scatter plot drawer.
Creates a scatter plot from multiple observers. Supports multiple series per observer. The series in a particular observer must share a common X column.
Example ¶
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
// Create a scatter plot.
app.AddUISystem((&window.Window{}).
With(&plot.Scatter{
Observers: []observer.Table{
&TableObserver{}, // One or more observers.
},
X: []string{
"X", // One X column per observer.
},
Y: [][]string{
{"A", "B", "C"}, // One or more Y columns per observer.
},
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Comment out the code line above, and uncomment the next line to run this example stand-alone.
//window.Run(app)
func (*Scatter) Initialize ¶
Initialize the drawer.
type TimeSeries ¶
type TimeSeries struct {
Observer observer.Row // Observer providing a data row per update.
Columns []string // Columns to show, by name. Optional, default all.
UpdateInterval int // Interval for getting data from the the observer, in model ticks. Optional.
Labels Labels // Labels for plot and axes. Optional.
MaxRows int // Maximum number of rows to keep. Zero means unlimited. Optional.
// contains filtered or unexported fields
}
TimeSeries plot drawer.
Creates a line series per column of the observer. Adds one row to the data per update.
Example ¶
package main
import (
"math/rand"
"github.com/mlange-42/ark-pixel/plot"
"github.com/mlange-42/ark-pixel/window"
"github.com/mlange-42/ark-tools/app"
"github.com/mlange-42/ark-tools/system"
"github.com/mlange-42/ark/ecs"
)
func main() {
// Create a new model.
app := app.New()
// Limit the the simulation speed.
app.TPS = 30
// Create a time series plot.
// See below for the implementation of the RowObserver.
app.AddUISystem((&window.Window{}).
With(&plot.TimeSeries{
Observer: &RowObserver{},
}))
// Add a termination system that ends the simulation.
app.AddSystem(&system.FixedTermination{
Steps: 100,
})
app.Run()
// Run the simulation.
// Due to the use of the OpenGL UI system, the model must be run via [window.Run].
// Uncomment the next line to run this example stand-alone.
//window.Run(app)
}
// RowObserver to generate random time series.
type RowObserver struct{}
func (o *RowObserver) Initialize(w *ecs.World) {}
func (o *RowObserver) Update(w *ecs.World) {}
func (o *RowObserver) Header() []string {
return []string{"A", "B", "C"}
}
func (o *RowObserver) Values(w *ecs.World) []float64 {
return []float64{rand.Float64(), rand.Float64() + 1, rand.Float64() + 2}
}
Output:
func (*TimeSeries) Draw ¶
func (t *TimeSeries) Draw(_ *ecs.World, win *opengl.Window)
Draw the drawer.
func (*TimeSeries) Initialize ¶
func (t *TimeSeries) Initialize(w *ecs.World, _ *opengl.Window)
Initialize the drawer.
func (*TimeSeries) UpdateInputs ¶
func (t *TimeSeries) UpdateInputs(_ *ecs.World, _ *opengl.Window)
UpdateInputs handles input events of the previous frame update.