ggbunch()¶The ggbunch() here combines two plots into a single figure with custom layout - a main scatter plot showing diamond price vs. carat weight colored by cut quality, and a zoomed-in inset that magnifies a specific region of interest.
import pandas as pd
from lets_plot import *
LetsPlot.setup_html()
df = pd.read_csv("https://raw.githubusercontent.com/JetBrains/lets-plot-docs/refs/heads/master/data/diamonds.csv")
print(df.shape)
df.head(3)
# Convert the 'cut' column to categorical data type with specified order
cut_categories = ['Fair', 'Good', 'Very Good', 'Premium', 'Ideal']
df['cut'] = pd.Categorical(df['cut'], categories=cut_categories, ordered=True)
p_base = (ggplot(df, aes("carat", "price", color="cut"))
+ geom_point()
+ geom_smooth(deg=2, size=1, tooltips='none')
+ scale_color_viridis(direction = -1)
)
# The region of interest
carat_min = 2.1
carat_max = 2.7
price_min = 12650
price_max = 17100
# The main plot
p_main = (p_base
+ geom_rect(xmin=carat_min,
xmax=carat_max,
ymin=price_min,
ymax=price_max,
alpha=0.4, inherit_aes=False, fill='white')
+ theme_grey()
+ coord_cartesian(ylim = [0, 20000])
+ theme(legend_position=[0.58, 0.02], legend_justification=[0, 0])
)
p_main
# The 'magnifier' plot
p_mag = (p_base
+ theme_minimal()
+ coord_cartesian(xlim=[carat_min, carat_max],
ylim=[price_min, price_max])
+ theme_void()
+ theme(legend_position='none', plot_inset=0)
)
p_mag
(ggbunch(
plots = [
(p_main
+ geom_segment(x=carat_min, y=price_min, xend=4.30, yend=5800, inherit_aes=False, size=0.5)
+ geom_segment(x=carat_min, y=price_max, xend=4.30, yend=19100, inherit_aes=False, size=0.5)
),
p_mag + theme(plot_background=element_rect(size=2, fill='rgba(255, 255, 255, 0.7)'))
],
regions = [
(0, 0, 0.9, 1),
(0.75, 0.05, 0.25, 0.6)
]
)
+ ggsize(900, 600)
+ ggtitle('Diamond Price vs. Carat Weight by Cut Quality')
+ theme(plot_title=element_text(hjust=0.5, size=18))
)