Is there a good way to plot multiple lines in lets...
# datascience
c
Is there a good way to plot multiple lines in letsplot with different y-axis scales? I have time series sensor data (e.g. think ECG versus accelerometer or unfiltered versus filtered waveforms), and having them overlayed but stretched for different y scales would be helpful for some analysis. ECG/accelerometer have totally different scales, while filtered data is 0 centered and raw data is not. I tried adding two geomLines on the same plot. They show up, but due to different y axis scales the lines aren’t readable. I also tried doing a GGBunch() without changing the x/y coordinates but only a single line shows up which makes me think one graph is completely covering the other. Other ideas or approaches for doing this?
This is an example of what I’m currently getting by adding two geomLines, but the different y scales make it hard to visually compare.
a
Not a lot of plotting libraries allow multiple axis scales. I am not sure about LetsPlot, but I remember that JFreeChart allows that.
c
JFreeChart was going to be my fallback, but hoping to leverage LetsPlot if possible to keep my codebase more sane 🙂
a
Well, unfortunately, there is no way in lets-plot to set several scales along one axis (. If I understand everything correctly,
facetGrid
with the parameterization of the
freeScales
parameter could help you!
a
NB for@Andrei Kislitsyn: I was talking about this case before. It is not frequent, but it does exist.
c
The best example I have is raw versus butterworth filtered waveforms, as I’m trying to see what kind of filter delay I’m dealing with. Once I get it graphed with JFreeChart I’ll share an example.
a
Another possible solution is to make one scale but with a transformation, for example
scaleYLog10
i
This wont work with values <=0 🙂
@Carter you can try GGBunch approach but set plot background color to transparent (via theme()) for the 2nd plot&
a
Well if you have negative values you can shift all the values to some offset, make a scale log and then change the labels)
i
also remove y-axis altogether.
c
OK, let me try the GGBunch approach and I’ll report back.
i
Perhaps, a better idea would be to have all the data (both lines) in 1
geomLine
layer and use
position = positionStack
on that layer to stack one line ontop of another.
c
Can you say more about the
position = positionStack
approach? I’m not sure I totally follow. I tried GGBunch with transparency but either I configured it incorrectly or I did something wrong. I got a graph with just a single line representing the first graph but with a different color background For the second plot, I added
Copy code
+ themeMinimal2() + theme(plotBackground = elementRect(fill=Color.TRANSPARENT, color = Color.TRANSPARENT))
i
I'll give you an example on `position`:
Copy code
val line1 = listOf(1.0, 1.2, 0.9)
val line2 = line1.map { it + 10000}
val line = line2 + line1 // <-- important: line2 goes 1st, line1 - 2nd

val dat = mapOf(
    "y" to line,
    "x" to List(line2.size) { it } + List(line1.size) { it },
    "c" to List(line2.size) { "line 2" } + List(line1.size) { "line 1" }
)
Now, if we simply create a line plot, the result is not useful:
Copy code
letsPlot(dat) + geomLine {
    x = "x"
    y = "y"
    color = "c"
}
But if we add stacking, then we will be able to compare values:
Copy code
letsPlot(dat) + geomLine(position = positionStack) {
    x = "x"
    y = "y"
    color = "c"
}
As for plot background, this code works for me:
Copy code
val dat2 = mapOf(
    "line1" to line1,
    "line2" to line2,
    "x" to List(line2.size) { it },
)

val bunch = GGBunch()

val t = theme(plotBackground = elementRect(fill = "rgba(0,0,0,0)"))

bunch.addPlot(letsPlot(dat2) + geomLine(color = "red") {x = "x"; y = "line1"}, 0, 0)
bunch.addPlot(letsPlot(dat2) + geomLine(color = "blue") {x = "x"; y = "line2"} + t, 0, 0)
Actually, the "facetGrid" approach coined by @Andrei Kislitsyn works the best IMO:
Copy code
letsPlot(dat) + geomLine {
    x = "x"
    y = "y"
    color = "c"
} + facetGrid(y="c", scales="free_y") + ggsize(600, 200)
a
It seems like Plotly actually allows multiple axis. So if the plot is for web, you can use it.
437 Views