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]:
Lets-Plot Kotlin API v.4.13.0. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.4.9.0.
Outputs: Web (HTML+JS), Kotlin Notebook (Swing), Static SVG (hidden)
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]:

DataFrame: rowsCount = 3, columnsCount = 9

miles per gallonnumber of cylindersengine displacement (cu. inches)engine horsepowervehicle weight (lbs.)time to accelerate (sec.)model yearorigin of carvehicle name
18.0000008307.000000130350412.00000070USchevrolet chevelle malibu
15.0000008350.000000165369311.50000070USbuick skylark 320
18.0000008318.000000150343611.00000070USplymouth satellite

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]:
origin of car US Asia Europe 10 20 30 40 50 2,000 3,000 4,000 5,000 Weight vs MPG vehicle weight (lbs.) miles per gallon 10 20 30 40 50 50 100 150 200 HP vs MPG engine horsepower miles per gallon 10 20 30 40 50 10 15 20 25 Accel vs MPG time to accelerate (sec.) miles per gallon 10 20 30 40 50 100 200 300 400 Displ vs MPG engine displacement (cu. inches) miles per gallon

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]:
origin of car US Asia Europe 100 200 300 400 10 20 30 40 50 MPG vs Displ miles per gallon engine displacement (cu. inches) 50 100 150 200 10 20 30 40 50 MPG vs HP miles per gallon engine horsepower 2,000 3,000 4,000 5,000 10 20 30 40 50 MPG vs Weight miles per gallon vehicle weight (lbs.) 10 15 20 25 10 20 30 40 50 MPG vs Accel miles per gallon time to accelerate (sec.)

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]:
origin of car US Asia Europe 10 20 30 40 50 2,000 3,000 4,000 5,000 Weight vs MPG vehicle weight (lbs.) miles per gallon 50 100 150 200 2,000 3,000 4,000 5,000 Weight vs HP vehicle weight (lbs.) engine horsepower 10 20 30 40 50 10 15 20 25 Accel vs MPG time to accelerate (sec.) miles per gallon 50 100 150 200 10 15 20 25 Accel vs HP time to accelerate (sec.) engine horsepower

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]:
20 40 50 100 150 200 US engine horsepower miles per gallon 20 40 50 100 150 200 Europe engine horsepower miles per gallon 20 40 50 100 150 200 Asia engine horsepower miles per gallon