Download notebook (.ipynb)

Creating Magnifier Inset Effect with 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)
(53940, 10)
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
# 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))
)