def graph_feature(feature, to_file=None, description=False, **kwargs):
    """Generates a feature lineage graph for the given feature

    Args:
        feature (FeatureBase) : Feature to generate lineage graph for
        to_file (str, optional) : Path to where the plot should be saved.
            If set to None (as by default), the plot will not be saved.
        description (bool or str, optional): The feature description to use as a caption
            for the graph. If False, no description is added. Set to True
            to use an auto-generated description. Defaults to False.
        kwargs (keywords): Additional keyword arguments to pass as keyword arguments
            to the ft.describe_feature function.

    Returns:
        graphviz.Digraph : Graph object that can directly be displayed in Jupyter notebooks.
    """
    graphviz = check_graphviz()
    format_ = get_graphviz_format(graphviz=graphviz, to_file=to_file)

    # Initialize a new directed graph
    graph = graphviz.Digraph(
        feature.get_name(),
        format=format_,
        graph_attr={"rankdir": "LR"},
    )

    dataframes = {}
    edges = ([], [])
    primitives = []
    groupbys = []

    _, max_depth = get_feature_data(
        feature,
        dataframes,
        groupbys,
        edges,
        primitives,
        layer=0,
    )
    dataframes[feature.dataframe_name]["targets"].add(feature.get_name())

    for df_name in dataframes:
        dataframe_name = (
            "\u2605 {} (target)".format(df_name)
            if df_name == feature.dataframe_name
            else df_name
        )
        dataframe_table = get_dataframe_table(dataframe_name, dataframes[df_name])
        graph.attr("node", shape="plaintext")
        graph.node(df_name, dataframe_table)

    graph.attr("node", shape="diamond")
    num_primitives = len(primitives)
    for prim_name, prim_label, layer, prim_type in primitives:
        step_num = max_depth - layer
        if num_primitives == 1:
            type_str = (
                '<FONT POINT-SIZE="12"><B>{}</B><BR></BR></FONT>'.format(prim_type)
                if prim_type
                else ""
            )
            prim_label = "<{}{}>".format(type_str, prim_label)
        else:
            step = "Step {}".format(step_num)
            type_str = "   " + prim_type if prim_type else ""
            prim_label = (
                '<<FONT POINT-SIZE="12"><B>{}:</B>{}<BR></BR></FONT>{}>'.format(
                    step,
                    type_str,
                    prim_label,
                )
            )

        # sink first layer transform primitive if multiple primitives
        if step_num == 1 and prim_type == "Transform" and num_primitives > 1:
            with graph.subgraph() as init_transform:
                init_transform.attr(rank="min")
                init_transform.node(name=prim_name, label=prim_label)
        else:
            graph.node(name=prim_name, label=prim_label)

    graph.attr("node", shape="box")
    for groupby_name, groupby_label in groupbys:
        graph.node(name=groupby_name, label=groupby_label)

    graph.attr("edge", style="solid", dir="forward")
    for edge in edges[1]:
        graph.edge(*edge)

    graph.attr("edge", style="dotted", arrowhead="none", dir="forward")
    for edge in edges[0]:
        graph.edge(*edge)

    if description is True:
        graph.attr(label=describe_feature(feature, **kwargs))
    elif description is not False:
        graph.attr(label=description)

    if to_file:
        save_graph(graph, to_file, format_)

    return graph
Generates a feature lineage graph for the given feature

    Args:
        feature (FeatureBase) : Feature to generate lineage graph for
        to_file (str, optional) : Path to where the plot should be saved.
            If set to None (as by default), the plot will not be saved.
        description (bool or str, optional): The feature description to use as a caption
            for the graph. If False, no description is added. Set to True
            to use an auto-generated description. Defaults to False.
        kwargs (keywords): Additional keyword arguments to pass as keyword arguments
            to the ft.describe_feature function.

    Returns:
        graphviz.Digraph : Graph object that can directly be displayed in Jupyter notebooks.
    
featuretools/feature_base/feature_visualizer.py