Interactive Pan/Zoom with Shared Axes in gggrid¶
When subplots in a gggrid share axes via sharex or sharey, interactive pan and zoom propagate across sibling plots. Zooming or panning one subplot automatically updates all plots sharing that axis.
Tip: double-click a subplot to reset it.
In [1]:
%useLatestDescriptors
%use dataframe
%use lets-plot
In [2]:
LetsPlot.getInfo()
Out[2]:
In [3]:
val df = DataFrame.readCSV("https://raw.githubusercontent.com/JetBrains/lets-plot-docs/refs/heads/master/data/mpg2.csv")
val data = df.toMap()
val mpg = "miles per gallon"
val wt = "vehicle weight (lbs.)"
val origin = "origin of car"
val hp = "engine horsepower"
val accel = "time to accelerate (sec.)"
val displ = "engine displacement (cu. inches)"
df.head(3)
Out[3]:
Shared X-axis (all)¶
In [4]:
val p1 = letsPlot(data) { x = mpg; y = wt } + geomPoint { color = origin } + ggtitle("Weight vs MPG")
val p2 = letsPlot(data) { x = mpg; y = hp } + geomPoint { color = origin } + ggtitle("HP vs MPG")
val p3 = letsPlot(data) { x = mpg; y = accel } + geomPoint { color = origin } + ggtitle("Accel vs MPG")
val p4 = letsPlot(data) { x = mpg; y = displ } + geomPoint { color = origin } + ggtitle("Displ vs MPG")
gggrid(listOf(p1, p2, p3, p4), ncol = 2, guides = "collect",
sharex = "all"
) + ggsize(800, 600) + ggtb()
Out[4]:
Shared Y-axis (all)¶
In [5]:
val p1 = letsPlot(data) { x = displ; y = mpg } + geomPoint { color = origin } + ggtitle("MPG vs Displ")
val p2 = letsPlot(data) { x = hp; y = mpg } + geomPoint { color = origin } + ggtitle("MPG vs HP")
val p3 = letsPlot(data) { x = wt; y = mpg } + geomPoint { color = origin } + ggtitle("MPG vs Weight")
val p4 = letsPlot(data) { x = accel; y = mpg } + geomPoint { color = origin } + ggtitle("MPG vs Accel")
gggrid(listOf(p1, p2, p3, p4), ncol = 2, guides = "collect",
sharey = "all"
) + ggsize(800, 600) + ggtb()
Out[5]:
Shared X by Column, Y by Row¶
In [6]:
val p1 = letsPlot(data) { x = mpg; y = wt } + geomPoint { color = origin } + ggtitle("Weight vs MPG")
val p2 = letsPlot(data) { x = hp; y = wt } + geomPoint { color = origin } + ggtitle("Weight vs HP")
val p3 = letsPlot(data) { x = mpg; y = accel } + geomPoint { color = origin } + ggtitle("Accel vs MPG")
val p4 = letsPlot(data) { x = hp; y = accel } + geomPoint { color = origin } + ggtitle("Accel vs HP")
gggrid(listOf(p1, p2, p3, p4), ncol = 2, guides = "collect",
sharex = "col",
sharey = "row"
) + ggsize(800, 600) + ggtb()
Out[6]:
Shared Both X and Y (all)¶
In [7]:
val p1 = letsPlot(df.filter { it[origin] == "US" }.toMap()) { x = mpg; y = hp } + geomPoint(color = "red") + ggtitle("US")
val p2 = letsPlot(df.filter { it[origin] == "Europe" }.toMap()) { x = mpg; y = hp } + geomPoint(color = "blue") + ggtitle("Europe")
val p3 = letsPlot(df.filter { it[origin] == "Asia" }.toMap()) { x = mpg; y = hp } + geomPoint(color = "green") + ggtitle("Asia")
gggrid(listOf(p1, p2, p3), ncol = 3,
sharex = "all",
sharey = "all"
) + ggsize(900, 350) + ggtb()
Out[7]: