我有两个函数,称为
update_y_with_x
和 update_x
如下:
更新_y_with_x
def update_y_with_x(chosen_tissue):
for i, trace in enumerate(f.data):
if trace.type == "scatter":
# reset all line width
f.data[i].line.width = 1
if chosen_tissue in trace.text:
f.data[i].line.width = 1 + 9
更新_x
def update_x(trace, points, selector):
if len(points.point_inds) == 0:
return
# Remove existing bar shades and linked lines' highlights
f.layout.shapes = ()
for i, trace in enumerate(f.data):
if trace.type == "scatter" and f.data[i].line.width != 1:
f.data[i].line.width = 1
# Get tissue identity
chosen_tissue = f.data[points.trace_index].y[points.point_inds[0]]
# Get the index of the chosen tissue
possible_trace_indices = [
i for i, trace in enumerate(f.data) if trace.type == "bar"
]
chosen_tissue_ranks = [
list(f.data[index].y).index(chosen_tissue) for index in possible_trace_indices
]
for i, _ in enumerate(possible_trace_indices):
# Specify the y-range around the clicked bar for shading
y0 = chosen_tissue_ranks[i] + 0.5
y1 = y0 - 1
f.add_hrect(
y0=y0,
y1=y1,
line_width=0,
fillcolor="grey",
opacity=0.3,
row=1,
col=i * 2 + 1,
)
# Update lines
update_y_with_x(chosen_tissue)
如你所见,update_x调用了update_y_with_x函数,目前,两者都使用硬编码的plotly gofigurewidget,其中
f = go.FigureWidget(fig)
并且这样称呼:
for i, trace in enumerate(f.data):
if trace.type == 'bar': # Check if it's a barplot
f.data[i].on_click(update_x)
我想做两件事:
将这两个函数移动到一个独立的函数文件中,并将它们导入到我正在使用的 main.ipynb 文件中
将
f
作为参数传递给每个函数,而不是像函数中当前存在的那样对其进行硬编码,并确保在将其用于 update_y_with_x
之前将其传递给
update_x
如果我错过了一些关键信息,请告诉我,我们将非常感谢您的帮助:)
编辑:
update_x
单击条形图上的事件。单击某个条形时,它会删除现有形状,重置链接散点图的线宽,在单击的条形周围添加阴影矩形,并更新将这些条形链接在一起的线条。
我尝试过的: 我最初将这些函数导出到一个名为“click_events.py”的新文件,并添加到每个
figure_widget
的参数中,如下所示:
def update_x(
trace, points, selector, figure_widget):
(替换文件中的 f)
def update_y_with_x(
chosen_tissue, figure_widget):
(替换文件中的 f)
修改
update_x
中的代码,使得update_y_with_x(chosen_tissue, figure_widget = figure_widget)
但是,我相信当我导入并尝试以上述方式运行这些函数时,figure_widget 不会传递给“update_y_with_x”。
对于您提到的两个目标 - 将函数移动到独立文件并传递
f
作为参数
创建一个新的 Python 文件(例如,我们称之为
plot_utils.py
)并将函数 update_y_with_x
和 update_bar
移动到该文件中。 plot_utils.py
的内容如下所示:
# plot_utils.py
import plotly.graph_objects as go
def update_y_with_x(fig, chosen_tissue):
for i, trace in enumerate(fig.data):
if trace.type == "scatter":
# reset all line width
fig.data[i].line.width = 1
if chosen_tissue in trace.text:
fig.data[i].line.width = 1 + 9
def update_bar(fig, trace, points, selector):
if len(points.point_inds) == 0:
return
# Remove existing bar shades and linked lines' highlights
fig.layout.shapes = ()
for i, trace in enumerate(fig.data):
if trace.type == "scatter" and fig.data[i].line.width != 1:
fig.data[i].line.width = 1
# Get tissue identity
chosen_tissue = fig.data[points.trace_index].y[points.point_inds[0]]
# Get the index of the chosen tissue
possible_trace_indices = [
i for i, trace in enumerate(fig.data) if trace.type == "bar"
]
chosen_tissue_ranks = [
list(fig.data[index].y).index(chosen_tissue) for index in possible_trace_indices
]
for i, _ in enumerate(possible_trace_indices):
# Specify the y-range around the clicked bar for shading
y0 = chosen_tissue_ranks[i] + 0.5
y1 = y0 - 1
fig.add_hrect(
y0=y0,
y1=y1,
line_width=0,
fillcolor="grey",
opacity=0.3,
row=1,
col=i * 2 + 1,
)
# Update lines
update_y_with_x(fig, chosen_tissue)
main.ipynb
) 中:在您的主 Jupyter Notebook 中,您可以导入这些函数并按如下方式使用它们:
# main.ipynb
import plot_utils
import plotly.graph_objects as go
# Create the initial figure
f = go.FigureWidget(fig)
# Register the on_click event
for i, trace in enumerate(f.data):
if trace.type == 'bar': # Check if it's a barplot
f.data[i].on_click(lambda trace, points, selector: plot_utils.update_bar(f, trace, points, selector))
现在,
update_y_with_x
和update_bar
都在一个单独的文件中,您可以在主笔记本中导入和使用它们。 f
数字作为参数传递给两个函数,使它们更加灵活并避免硬编码。