在 Python 中将参数传递给嵌套函数

问题描述 投票:0回答:1

我有两个函数,称为

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)

我想做两件事:

  1. 将这两个函数移动到一个独立的函数文件中,并将它们导入到我正在使用的 main.ipynb 文件中

  2. 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”。

python nested plotly
1个回答
0
投票

对于您提到的两个目标 - 将函数移动到独立文件并传递

f
作为参数

步骤:

1.创建独立的函数文件:

创建一个新的 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)

2.在您的主 Jupyter 笔记本 (
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
数字作为参数传递给两个函数,使它们更加灵活并避免硬编码。

© www.soinside.com 2019 - 2024. All rights reserved.