# %%
import numpy as np
import pandas as pd
import solara
import altair as alt
# Generate some example data for the graph
def generate_data(n_residues=200):
residues = range(1, n_residues + 1)
values = np.random.rand(n_residues) * 100 # Random values between 0 and 100
return pd.DataFrame({"residue": residues, "value": values})
# %%
data = generate_data(n_residues=200)
np.random.seed(42)
# Create a selection that chooses the nearest point & selects based on x-value
nearest = alt.selection_point(
name="point", nearest=True, on="pointerover", fields=["residue"], empty=False
)
# The basic line
line = (
alt.Chart(data)
.mark_circle(interpolate="basis")
.encode(
x="residue:Q",
y="value:Q",
)
)
# Transparent selectors across the chart. This is what tells us
# the x-value of the cursor
selectors = (
alt.Chart(data)
.mark_point()
.encode(
x="residue:Q",
opacity=alt.value(0),
)
.add_params(nearest)
)
# Draw points on the line, and highlight based on selection
points = line.mark_point().encode(
opacity=alt.condition(nearest, alt.value(1), alt.value(0))
)
# Draw a rule at the location of the selection
rules = (
alt.Chart(data)
.mark_rule(color="gray")
.encode(
x="residue:Q",
)
.transform_filter(nearest)
)
# Put the five layers into a chart and bind the data
chart = alt.layer(line, selectors, points, rules).properties(width=600, height=300)
@solara.component
def Page():
r_number = solara.use_reactive(None)
view = alt.JupyterChart.element(chart=chart)
def bind():
real = solara.get_widget(view)
real.selections.observe(on_selections, "point")
solara.use_effect(bind, [])
def on_selections(event):
try:
r = event["new"].value[0]["residue"]
r_number.set(r)
except (IndexError, KeyError):
r_number.set(None)
solara.Text(f"Residue: {r_number.value}")
view