<jupyter_start><jupyter_text>dual plot troubleshooting__objective__: get 2x separate plots in a single interactive visualization (normal Michaelis-Menten kinetics and Lineweaver-Burk), and have both plots be controled by the sliders changing Vmax and Km__plan__: 1. set the input data and plot limits on each of the plots to be identical so they can be controlled by the same set of sliders* get the row layout optimized, statically* try to figure out how to convert both plots to a dynamic layout<jupyter_code># import libraries
import os
import sys
import numpy as np
import matplotlib.pyplot as plt

from bokeh.layouts import row, column
from bokeh.models import CustomJS, Slider, Label, Span
from bokeh.plotting import figure, output_file, show, ColumnDataSource
from bokeh.io import output_notebook

root_dir = os.path.join(os.getcwd(), '..')
sys.path.append(root_dir)

from pharmaplot import mm
# set to display in notebook as opposed to making an html
output_notebook()<jupyter_output><empty_output><jupyter_text>match axes, sliders of mm plot to establish lb plot<jupyter_code>## generate bokeh plot using the following data
log_start = -2
log_end = 3
vmax = 10
km = 1

x_line = np.logspace(log_start, log_end, num=100)
y_line = mm.michaelis_menten(x_line, vmax, km)

x_points = np.logspace(log_start, log_end, num=20)
y_points = mm.michaelis_menten(x_points, vmax, km)

# set up source data and plot lines that will vary
line_source = ColumnDataSource(data=dict(x=x_line, y=y_line))
point_source = ColumnDataSource(data=dict(x=x_points, y=y_points))

plot = figure(y_range=(-0.5, 20), x_range=(-0.5, 10), plot_width=600, plot_height=400, 
              x_axis_label='[S]: substrate concentration (μM)',
              y_axis_label='initial velocity (μM/s)',
              title='Michaelis-Menten Kinetics')

plot.line('x', 'y', source=line_source, line_width=3, line_alpha=0.6, color='black')
plot.circle('x', 'y', source=point_source, size=10, color='black')

# set up static line and annotations
plot.line(x_line, y_line, line_width=5, color='blue', line_alpha=0.3)
plot.circle(x_points, y_points, size=10, color='blue', line_alpha=0.3)

mytext = Label(x=50, y=70, text='Km = 10 (μM), Vmax = 100 (μM/s)', 
               text_color="blue", text_alpha=0.5)
plot.add_layout(mytext)

# add axes lines
vline = Span(location=0, dimension='height', line_color='black', line_width=1, line_alpha=0.3)
hline = Span(location=0, dimension='width', line_color='black', line_width=1, line_alpha=0.3)
plot.renderers.extend([vline, hline])

# set up java script callback function to make plot interactive
vmax_slider = Slider(start=0, end=20, value=10, step=0.1, title="Vmax (μM/s)")
km_slider = Slider(start=0.1, end=10, value=1, step=0.1, title="Km (μM)")

callback = CustomJS(args=dict(LineSource=line_source, 
                              PointSource=point_source,
                              vmax=vmax_slider, 
                              km=km_slider),
                    code="""
    const LineData = LineSource.data;
    const PointData = PointSource.data;
    const VMAX = vmax.value;
    const KM = km.value;
    const lx = LineData['x']
    const ly = LineData['y']
    const px = PointData['x']
    const py = PointData['y']
    for (var i = 0; i < lx.length; i++) {
        ly[i] = (VMAX*lx[i])/(KM+lx[i]);
    }
    LineSource.change.emit();
    for (var i = 0; i < px.length; i++) {
    py[i] = (VMAX*px[i])/(KM+px[i]);
    }
    PointSource.change.emit();
""")

# add sliders to plot and display
vmax_slider.js_on_change('value', callback)
km_slider.js_on_change('value', callback)

layout = row(
    plot,
    column(vmax_slider, km_slider),
)

#output_file("mm.html", title="mm.py example")
show(layout)<jupyter_output><empty_output><jupyter_text>optimize getting two plots on one visualization<jupyter_code># -------------------------------------------------
# create baseline michaelis-menten plot
# -------------------------------------------------
# set plot parameters
pw = 500
ph = 400

# set data values
log_start = -2
log_end = 3
vmax = 10
km = 1

# -------------------------------------------------
# create baseline michaelis-menten plot
# -------------------------------------------------
# set up starting values
x_line = np.logspace(log_start, log_end, num=100)
y_line = mm.michaelis_menten(x_line, vmax, km)

x_points = np.logspace(log_start, log_end, num=20)
y_points = mm.michaelis_menten(x_points, vmax, km)

# set up source data and plot lines that will vary
mm_line_source = ColumnDataSource(data=dict(x=x_line, y=y_line))
mm_point_source = ColumnDataSource(data=dict(x=x_points, y=y_points))

mm_plot = figure(y_range=(-0.5, 20), x_range=(-0.5, 10), plot_width=pw, plot_height=ph, 
              x_axis_label='[S]: substrate concentration (μM)',
              y_axis_label='initial velocity (μM/s)',
              title='Michaelis-Menten Kinetics')

mm_plot.line('x', 'y', source=mm_line_source, line_width=3, line_alpha=0.6, color='black')
mm_plot.circle('x', 'y', source=mm_point_source, size=10, color='black')

# set up static line and annotations
mm_plot.line(x_line, y_line, line_width=5, color='blue', line_alpha=0.3)
mm_plot.circle(x_points, y_points, size=10, color='blue', line_alpha=0.3)

mytext = Label(x=50, y=70, text='Km = 10 (μM), Vmax = 100 (μM/s)', 
               text_color="blue", text_alpha=0.5)
mm_plot.add_layout(mytext)

# add axes lines
vline = Span(location=0, dimension='height', line_color='black', line_width=1, line_alpha=0.3)
hline = Span(location=0, dimension='width', line_color='black', line_width=1, line_alpha=0.3)
mm_plot.renderers.extend([vline, hline])

# -------------------------------------------------
# create baseline lineweaver-burk plot
# -------------------------------------------------
x_line = np.linspace(-3, np.max(x_points))
y_line = mm.lineweaver_burk(x_line, vmax, km)

x_points = 1 / np.geomspace(0.1, 10, num=8)
y_points = mm.lineweaver_burk(x_points, vmax, km)

# set up source data and plot lines that will vary
lb_line_source = ColumnDataSource(data=dict(x=x_line, y=y_line))
lb_point_source = ColumnDataSource(data=dict(x=x_points, y=y_points))

lb_plot = figure(y_range=(-0.05, 0.8), x_range=(-1.5, 4), plot_width=pw, plot_height=ph, 
              x_axis_label='1/[S]: substrate concentration (1/μM)',
              y_axis_label='1/initial velocity (s/μM)',
              title='Lineweaver-Burk Kinetics')

lb_plot.line('x', 'y', source=lb_line_source, line_width=3, line_alpha=0.6, color='black')
lb_plot.circle('x', 'y', source=lb_point_source, size=10, color='black')

# add axes lines
vline = Span(location=0, dimension='height', line_color='black', line_width=1, line_alpha=0.3)
hline = Span(location=0, dimension='width', line_color='black', line_width=1, line_alpha=0.3)
lb_plot.renderers.extend([vline, hline])

# set up static line and annotations
lb_plot.line(x_line, y_line, line_width=5, color='blue', line_alpha=0.3)
lb_plot.circle(x_points, y_points, size=10, color='blue', line_alpha=0.3)

mytext = Label(x=0.3, y=0.4, text='Km = 1 (μM), Vmax = 10 (μM/s)', 
               text_color="blue", text_alpha=0.5)
lb_plot.add_layout(mytext)

# -------------------------------------------------
# make plot interactive
# -------------------------------------------------
# set up java script callback function to make plot interactive
vmax_slider = Slider(start=0, end=20, value=10, step=0.1, title="Vmax (μM/s)")
km_slider = Slider(start=0.1, end=10, value=1, step=0.1, title="Km (μM)")

callback = CustomJS(args=dict(LineSource=mm_line_source, 
                              PointSource=mm_point_source,
                              vmax=vmax_slider, 
                              km=km_slider),
                    code="""
    const LineData = LineSource.data;
    const PointData = PointSource.data;
    const VMAX = vmax.value;
    const KM = km.value;
    const lx = LineData['x']
    const ly = LineData['y']
    const px = PointData['x']
    const py = PointData['y']
    for (var i = 0; i < lx.length; i++) {
        ly[i] = (VMAX*lx[i])/(KM+lx[i]);
    }
    LineSource.change.emit();
    for (var i = 0; i < px.length; i++) {
    py[i] = (VMAX*px[i])/(KM+px[i]);
    }
    PointSource.change.emit();
""")

# add sliders to plot and display
vmax_slider.js_on_change('value', callback)
km_slider.js_on_change('value', callback)

# -------------------------------------------------
# create baseline michaelis-menten plot
# -------------------------------------------------
layout = row(
    mm_plot,
    lb_plot,
    column(vmax_slider, km_slider),
)

#output_file("mm.html", title="mm.py example")
show(layout)<jupyter_output><empty_output><jupyter_text>getting both plots interactiveI think if I just add more lines into the javascript, and pass both inputs in, I can pull this off just fine ...<jupyter_code># -------------------------------------------------
# create baseline michaelis-menten plot
# -------------------------------------------------
# set plot parameters
pw = 500
ph = 400

# set data values
log_start = -2
log_end = 3
vmax = 10
km = 1

# -------------------------------------------------
# create baseline michaelis-menten plot
# -------------------------------------------------
# set up starting values
x_line = np.logspace(log_start, log_end, num=100)
y_line = mm.michaelis_menten(x_line, vmax, km)

x_points = np.logspace(log_start, log_end, num=20)
y_points = mm.michaelis_menten(x_points, vmax, km)

# set up source data and plot lines that will vary
mm_line_source = ColumnDataSource(data=dict(x=x_line, y=y_line))
mm_point_source = ColumnDataSource(data=dict(x=x_points, y=y_points))

mm_plot = figure(y_range=(-0.5, 20), x_range=(-0.5, 10), plot_width=pw, plot_height=ph, 
              x_axis_label='[S]: substrate concentration (μM)',
              y_axis_label='initial velocity (μM/s)',
              title='Michaelis-Menten Kinetics')

mm_plot.line('x', 'y', source=mm_line_source, line_width=3, line_alpha=0.6, color='black')
mm_plot.circle('x', 'y', source=mm_point_source, size=10, color='black')

# set up static line and annotations
mm_plot.line(x_line, y_line, line_width=5, color='blue', line_alpha=0.3)
mm_plot.circle(x_points, y_points, size=10, color='blue', line_alpha=0.3)

mytext = Label(x=50, y=70, text='Km = 10 (μM), Vmax = 100 (μM/s)', 
               text_color="blue", text_alpha=0.5)
mm_plot.add_layout(mytext)

# add axes lines
vline = Span(location=0, dimension='height', line_color='black', line_width=1, line_alpha=0.3)
hline = Span(location=0, dimension='width', line_color='black', line_width=1, line_alpha=0.3)
mm_plot.renderers.extend([vline, hline])

# -------------------------------------------------
# create baseline lineweaver-burk plot
# -------------------------------------------------
x_line = np.linspace(-3, np.max(x_points))
y_line = mm.lineweaver_burk(x_line, vmax, km)

x_points = 1 / np.geomspace(0.1, 10, num=8)
y_points = mm.lineweaver_burk(x_points, vmax, km)

# set up source data and plot lines that will vary
lb_line_source = ColumnDataSource(data=dict(x=x_line, y=y_line))
lb_point_source = ColumnDataSource(data=dict(x=x_points, y=y_points))

lb_plot = figure(y_range=(-0.05, 0.8), x_range=(-1.5, 4), plot_width=pw, plot_height=ph, 
              x_axis_label='1/[S]: substrate concentration (1/μM)',
              y_axis_label='1/initial velocity (s/μM)',
              title='Lineweaver-Burk Kinetics')

lb_plot.line('x', 'y', source=lb_line_source, line_width=3, line_alpha=0.6, color='black')
lb_plot.circle('x', 'y', source=lb_point_source, size=10, color='black')

# add axes lines
vline = Span(location=0, dimension='height', line_color='black', line_width=1, line_alpha=0.3)
hline = Span(location=0, dimension='width', line_color='black', line_width=1, line_alpha=0.3)
lb_plot.renderers.extend([vline, hline])

# set up static line and annotations
lb_plot.line(x_line, y_line, line_width=5, color='blue', line_alpha=0.3)
lb_plot.circle(x_points, y_points, size=10, color='blue', line_alpha=0.3)

mytext = Label(x=0.3, y=0.4, text='Km = 1 (μM), Vmax = 10 (μM/s)', 
               text_color="blue", text_alpha=0.5)
lb_plot.add_layout(mytext)

# -------------------------------------------------
# make plot interactive
# -------------------------------------------------
# set up java script callback function to make plot interactive
vmax_slider = Slider(start=0, end=20, value=10, step=0.1, title="Vmax (μM/s)")
km_slider = Slider(start=0.1, end=10, value=1, step=0.1, title="Km (μM)")

callback = CustomJS(args=dict(mmLineSource=mm_line_source, 
                              mmPointSource=mm_point_source,
                              lbLineSource=lb_line_source,
                              lbPointSource=lb_point_source,
                              vmax=vmax_slider, 
                              km=km_slider),
                    code="""
    const mmLineData = mmLineSource.data;
    const mmPointData = mmPointSource.data;
    const lbLineData = lbLineSource.data;
    const lbPointData = lbPointSource.data;
    const VMAX = vmax.value;
    const KM = km.value;
    const mmlx = mmLineData['x']
    const mmly = mmLineData['y']
    const mmpx = mmPointData['x']
    const mmpy = mmPointData['y']
    const lblx = lbLineData['x']
    const lbly = lbLineData['y']
    const lbpx = lbPointData['x']
    const lbpy = lbPointData['y']
    for (var i = 0; i < mmlx.length; i++) {
        mmly[i] = (VMAX*mmlx[i])/(KM+mmlx[i]);
    }
    mmLineSource.change.emit();
    for (var i = 0; i < mmpx.length; i++) {
        mmpy[i] = (VMAX*mmpx[i])/(KM+mmpx[i]);
    }
    mmPointSource.change.emit();
    for (var i = 0; i < lblx.length; i++) {
        lbly[i] = ((KM/VMAX)*lblx[i]) + (1/VMAX);
    }
    lbLineSource.change.emit();
    for (var i = 0; i < lbpx.length; i++) {
        lbpy[i] = ((KM/VMAX)*lbpx[i]) + (1/VMAX);
    }
    lbPointSource.change.emit();
""")

# add sliders to plot and display
vmax_slider.js_on_change('value', callback)
km_slider.js_on_change('value', callback)

# -------------------------------------------------
# create baseline michaelis-menten plot
# -------------------------------------------------
layout = row(
    mm_plot,
    lb_plot,
    column(vmax_slider, km_slider),
)

#output_file("mm.html", title="mm.py example")
show(layout)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.20188415910676902, 'fraction_numerical': 0.02184228890439637, 'mean_word_length': 2.942503438789546, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '524394', 'license': 'MIT', 'n_tokens_mistral': 5119, 'n_tokens_neox': 4912, 'n_words': 1113, 'path': 'notebooks/20-04-21_dual-plot-troubleshooting.ipynb', 'repo_name': 'praelfj/pharm-interactive-plotting', 'size': '14330'}