I continued a bit and created this for comparison of any panels: Images, Plots, Maps, Tables etc. I’m just a little bit happy about it 
after = data.hvplot().opts(color="red", line_width=6, responsive=True, height=700)
before = data.hvplot().opts(color="green", line_width=6, responsive=True, height=700)
before_after = BeforeAfterSlider(
value=20,after=after,before=before, height=800
)
import panel as pn
import param
import hvplot.pandas
pn.extension(sizing_mode="stretch_width")
ACCENT_COLOR="#D2386C"
CSS = """
.before-after-container {
position: relative;
height:100%;
width:100%
}
.before-after-container .outer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.before-after-container .inner,
{
height: 100%
}
.before-after-container .slider {
position: absolute;
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 100%;
outline: none;
margin: 0;
transition: all 0.2s;
display: flex;
justify-content: center;
align-items: center;
--track-width: 0;
}
.before-after-container .slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 12px;
height: 99%;
background: silver;
cursor: pointer;
border-radius: 8px
}
.before-after-container .slider::-moz-range-thumb {
width: 12px;
height: 99%;
background: silver;
cursor: pointer;
border-radius: 8px
}
"""
pn.config.raw_css.append(CSS)
class BeforeAfterSlider(pn.reactive.ReactiveHTML):
value = param.Integer(50, bounds=(0,100))
before = param.Parameter(allow_None=False)
after = param.Parameter(allow_None=False)
slider_width = param.Integer(default=12, bounds=(0,100))
slider_color = param.Color(default="silver")
_template = """
<style>
.before-after-container .slider::-webkit-slider-thumb {
width: ${slider_width}px;
background: ${slider_color};
}
.before-after-container .slider::-moz-range-thumb {
width: ${slider_width}px;
background: ${slider_color};
}
</style>
<div id="container" class='before-after-container'>
<div id="before" class='outer'>
<div id="before_inner" class="inner" >${before}</div>
</div>
<div id="after" class='outer' style="overflow:hidden">
<div id="after_inner" class="inner">${after}</div>
</div>
<input type="range" min="1" max="100" value="${value}" class="slider" name='slider' id="slider" oninput="${script('handle_change')}"></input>
</div>
"""
_scripts = {
"render": """
state.before_inner=before.children[0]
state.after_inner=after.children[0]
function setImageWidth(){
width=view.el.offsetWidth-12
state.after_inner.style.width=`${width}px`
state.before_inner.style.width=`${width}px`
}
setImageWidth()
window.addEventListener("resize", setImageWidth);
adjustment = parseInt((100-data.value)/100*18)
after.style.width=`calc(${data.value}% - ${adjustment}px)`
""",
"handle_change": """
const sliderPos = parseInt(event.target.value);
adjustment = parseInt((100-sliderPos)/100*18)
after.style.width=`calc(${sliderPos}% - ${adjustment}px)`
data.value=parseInt(sliderPos)
""",
"value": """
const sliderPos = data.value
adjustment = parseInt((100-data.value)/100*18)
after.style.width=`calc(${sliderPos}% - ${adjustment}px)`
"""
}
import pandas as pd
data = pd.DataFrame({"y": range(10)})
after = data.hvplot().opts(color="red", line_width=6, responsive=True, height=700)
before = data.hvplot().opts(color="green", line_width=6, responsive=True, height=700)
before_after = BeforeAfterSlider(
value=20,after=after,before=before, height=800
)
controls = pn.Param(before_after, parameters=["value", "slider_width", "slider_color"])
pn.template.FastListTemplate(
site="Awesome Panel", title="Before After Slider",
sidebar=[controls], main=[before_after],
accent_base_color=ACCENT_COLOR, header_background=ACCENT_COLOR
).servable()