Py.Cafe

jhsmit/

altair-interactive-residue-visualization

Altair Interactive Residue Visualization

DocsPricing
  • app.py
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# %%
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