ggbunch()
: Combining Plots with Custom Layout¶ggbunch()
provides a flexible way to combine multiple plots into a single figure.
Unlike grid-based layouts, it allows precise positioning and sizing of each plot using relative coordinates.
You can place plots anywhere within the container, adjust their sizes individually,
and fine-tune their positions with pixel-level offsets.
import pandas as pd
import geopandas as gpd
from lets_plot import *
from lets_plot.geo_data import * # Geo-coding
The geodata is provided by © OpenStreetMap contributors and is made available here under the Open Database License (ODbL).
LetsPlot.setup_html()
df_volc = pd.read_csv("https://raw.githubusercontent.com/JetBrains/lets-plot-docs/refs/heads/master/data/volcano_indo.csv", encoding='utf-8')
df_volc.head(3)
Unnamed: 0 | Name | Shape | Elevation | Last_Eruption | Geo_Location | Island | |
---|---|---|---|---|---|---|---|
0 | 0 | Weh | stratovolcano | 617 metres (2,024 ft) | Pleistocene | 5.82°N 95.28°E | Sumatra |
1 | 1 | Seulawah Agam | stratovolcano | 1,810 metres (5,940 ft) | 1839 (2) | 5.448°N 95.658°E | Sumatra |
2 | 2 | Peuet Sague | complex volcano | 2,801 metres (9,190 ft) | 25 December 2000 (2) | 4.914°N 96.329°E | Sumatra |
def dms_to_decimal(dms_string):
"""
Convert DMS coordinates to decimal degrees.
>>> dms_to_decimal("99.539°E")
99.539
>>> dms_to_decimal("99.539°W")
-99.539
"""
degrees, direction = dms_string.split('°')
degrees = float(degrees)
# Adjusting the sign based on direction
if direction in ['S', 'W']:
degrees *= -1
return degrees
df_volc = df_volc.dropna(subset=['Geo_Location'])
# Split 'Geo_Location' str.
lat_lon_dms = df_volc.Geo_Location.str.split(' ').apply(lambda lst: lst[1:3])
# Remove BOM symbols (\ufeff) and
# convert DMS strings to decimal degrees.
lat_lon_dd = lat_lon_dms.apply(lambda lst: [dms_to_decimal(v.replace('\ufeff', '')) for v in lst])
# Create a Geodataframe by adding the 'geometry' column.
latitudes = lat_lon_dd.apply(lambda pair: pair[0])
longitudes = lat_lon_dd.apply(lambda pair: pair[1])
gdf_volc = gpd.GeoDataFrame(df_volc, geometry=gpd.points_from_xy(longitudes, latitudes))
gdf_volc.head(3)
Unnamed: 0 | Name | Shape | Elevation | Last_Eruption | Geo_Location | Island | geometry | |
---|---|---|---|---|---|---|---|---|
0 | 0 | Weh | stratovolcano | 617 metres (2,024 ft) | Pleistocene | 5.82°N 95.28°E | Sumatra | POINT (95.28000 5.82000) |
1 | 1 | Seulawah Agam | stratovolcano | 1,810 metres (5,940 ft) | 1839 (2) | 5.448°N 95.658°E | Sumatra | POINT (95.65800 5.44800) |
2 | 2 | Peuet Sague | complex volcano | 2,801 metres (9,190 ft) | 25 December 2000 (2) | 4.914°N 96.329°E | Sumatra | POINT (96.32900 4.91400) |
# Map of Indonesia
indonesia_gcoder = geocode_countries('Indonesia')
indonesia_map = (ggplot()
+ geom_map(map=indonesia_gcoder, size=0.5)
# The Equator
+ geom_hline(yintercept=0, linetype="dotted", tooltips='none')
# Volcanoes
+ geom_point(data=gdf_volc, color='#fddbc7', tooltips=layer_tooltips()
.title("@Name")
.line("Last Eruption | @Last_Eruption"))
+ theme_void() + theme(plot_inset=0)
)
indonesia_map + ggsize(800, 304)
# Map of Southeast Asia
southeast_asia_gcoder = geocode_countries(['Indonesia',
'Australia', 'Malaysia', 'Thailand', 'Taiwan', 'Vietnam',
'Philippines', 'Papua New Guinea', 'Palau',
'Myanmar', 'Laos', 'Cambodia',
'Indonesia', 'India', 'Bangladesh', 'China',
'Bhutan', 'Nepal', 'Sri Lanka',
'South Korea', 'North Korea', 'Japan'
])
southeast_asia_map = (ggplot()
+ geom_map(map=southeast_asia_gcoder, fill='paper', size=0.1)
# The Equator
+ geom_hline(yintercept=0, linetype="dotted", tooltips='none')
# Indonesia bounding box
+ geom_rect(map=indonesia_gcoder, size=0.2, fill='paper', alpha=0.3, color='red')
+ theme_grey() + theme(axis='blank', panel_grid='blank')
+ theme(plot_background=element_rect(size=1), plot_inset=0)
)
southeast_asia_map
ggbunch()
¶(ggbunch(
plots=[indonesia_map, southeast_asia_map],
regions=[(0, 0, 1, 1), # <- Indonesia map takes 100% of available space
(0.85, 0, 0.15, 0.53, # <- Southeast Asia inset map
-10, 0) # <- Offset in px for precise positioning
]
)
+ theme(plot_background=element_rect(size=1), plot_inset=0,
plot_title=element_text(family='bold', size=20, hjust=0.5, color='#1a1a1a'))
+ ggtitle('Indonesia Volcanic Activity')
+ ggsize(800, 325)
)