Line & Scatter Plots
Plotting lines and points in 2-d
Basics
A line plot requires a list of data points, (x, y) pairs, with the data type and in the coordinate system of the axes provided to the enclosing XYGraph
. As an example, we want to plot the function \( y=x^2 \) with x from 1 to 10 with two Float axes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| val data = buildList {
for (i in 1..10) {
add(DefaultPoint(i.toFloat(), i * i.toFloat()))
}
}
XYGraph(
rememberFloatLinearAxisModel(data.autoScaleXRange()),
rememberFloatLinearAxisModel(data.autoScaleYRange())
) {
LinePlot(
data,
lineStyle = LineStyle(SolidColor(Color.Blue))
)
}
|
/examples/src/jvmMain/kotlin/io/github/koalaplot/example/Line1.ktLines 1-5 generate the data to plot. The data for Line plots is a list of x, y coordinates provided by an implementation of the
Point interface. This example uses the provided implementation,
DefaultPoint.
Lines 8 and 9 provide an AxisModel for each of the x and y axes to XYChart. In this case, we are using linear axes with floating point values (other types are covered in XY Graphs) and ranges that are calculated with the
calls to autoScaleXRange()
and autoScaleYRange()
.
Lines 11 through 13 call the LineChart
Composable to render the line itself, using a solid blue style.
Adding a Second Line
Now lets add a second line plotting the function \( y=e^{\sqrt{x}} \), which looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| XYGraph(
rememberFloatLinearAxisModel(dataSquared.autoScaleXRange()),
rememberFloatLinearAxisModel(dataSquared.autoScaleYRange())
) {
LinePlot(
dataSquared,
lineStyle = LineStyle(SolidColor(Color.Blue))
)
LinePlot(
dataExp,
lineStyle = LineStyle(
SolidColor(Color(0, 200, 0)),
2.dp,
dashPathEffect(floatArrayOf(20f, 10f))
)
)
}
|
/examples/src/jvmMain/kotlin/io/github/koalaplot/example/Line2.ktScatter Plots
A scatter plot is very similar to a line plot, and uses the same LinePlot
Composable function, except instead of lines connecting data points a symbol is drawn at each data point. In Koala Plot, the symbols are themselves Composables, and to make it even simpler provides the
Symbol Composable to make it easy to use a Shape with any fill and outline. Beyond the standard Compose circle and rectangle shapes, Koala Plot also defines additional shapes that are common for graphs, such as the
TriangleShape and
DiamondShape.
The below example illustrates a scatter plot using the default RectangleShape
used by Symbol
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| val data = buildList {
val random = Random(10)
for (i in 1..50) {
val x = random.nextDouble(1.0, 10.0).toFloat()
val y = (x + (random.nextDouble() - 0.5) * 2.0).toFloat()
add(DefaultPoint(x, y))
}
}
XYGraph(
rememberFloatLinearAxisModel(0f..12f),
rememberFloatLinearAxisModel(0f..12f)
) {
LinePlot(
data,
symbol = { Symbol(fillBrush = SolidColor(Color.Blue), outlineBrush = SolidColor(Color.Black)) }
)
}
|
/examples/src/jvmMain/kotlin/io/github/koalaplot/example/Scatter1.ktCombining Lines & Symbols
Combining lines and symbols on a single XYGraph
is as simple as repeatedly using LinePlot
for each data series to be plotted. The below example illustrates the scatter plot from the previous example, together with a plot of a line.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| val data = buildList {
val random = Random(10)
for (i in 1..50) {
val x = random.nextDouble(1.0, 10.0).toFloat()
val y = (x + (random.nextDouble() - 0.5) * 2.0).toFloat()
add(DefaultPoint(x, y))
}
}
val line = buildList {
add(DefaultPoint(-5f, -5f))
add(DefaultPoint(15f, 15f))
}
XYGraph(
rememberFloatLinearAxisModel(0f..12f),
rememberFloatLinearAxisModel(0f..12f)
) {
LinePlot(line, lineStyle = LineStyle(SolidColor(Color.Blue)))
LinePlot(
data,
symbol = { Symbol(fillBrush = SolidColor(Color.Blue), outlineBrush = SolidColor(Color.Black)) }
)
}
|
/examples/src/jvmMain/kotlin/io/github/koalaplot/example/Scatter2.ktThe z-order of the plots corresponds to the order in which they appear in the XYGraph
, so in this example the line is plotted first, and the rectangle symbols are plotted second and draw over the line.
It is also possible to plot both lines and symbols with the same LinePlot
, as illustrated below, which is a modification of the previous example plotting the function \( y=x^2 \).
1
2
3
4
5
| LinePlot(
data,
lineStyle = LineStyle(SolidColor(Color.Blue)),
symbol = { Symbol(fillBrush = SolidColor(Color.Blue), outlineBrush = SolidColor(Color.Black)) }
)
|
/examples/src/jvmMain/kotlin/io/github/koalaplot/example/Line3.ktStairStep Plots
The
StairstepPlot is a variant of a line plot that draws series as points and stairsteps between points. A simple example is shown below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| val data = buildList {
for (i in 1..10) {
add(DefaultPoint(i.toFloat(), i * i.toFloat()))
}
}
XYGraph(
rememberFloatLinearAxisModel(data.autoScaleXRange()),
rememberFloatLinearAxisModel(data.autoScaleYRange())
) {
StairstepPlot(
data,
lineStyle = LineStyle(SolidColor(Color.Blue))
)
}
|
/examples/src/jvmMain/kotlin/io/github/koalaplot/example/Stairstep1.ktA variant of StairstepPlot lets you specify a line style for each level. This is illustrated below where the coloring
of the step at each level is varied according to the y-axis value.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| val data = buildList {
for (i in 1..10) {
add(DefaultPoint(i.toFloat(), i * i.toFloat()))
}
}
XYGraph(
rememberFloatLinearAxisModel(data.autoScaleXRange()),
rememberFloatLinearAxisModel(data.autoScaleYRange())
) {
StairstepPlot(
data,
lineStyle = LineStyle(SolidColor(Color.Transparent)),
levelLineStyle = { y ->
LineStyle(SolidColor(Color(red = y / 100f, green = 0f, blue = 0f)), strokeWidth = 4.dp)
}
)
}
|
/examples/src/jvmMain/kotlin/io/github/koalaplot/example/Stairstep2.ktLast modified April 23, 2024:
Changes for 0.6.0 (19018a1)