[Python] Can't control what variable to dodge on using so.dodge

Discussão em 'Python' iniciado por Stack, Abril 16, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to pass a list of variables to the so.Dodge function of seaborn objects, so that in my plot provided in the following example, the dodge is applied only on two of three possible variables. In my example, this would translate to dots being arranged in columns of same "day", represented by the x-coordinate and "type", represented by the color, but not necessarily of the same "individual", represented by the shape.
    However, in my case passing a list of variables to Dodge through the by argument seems to ignore all variables except the first one.
    i.e. so.Dodge(by=["x"]) and so.Dodge(by=["x","type"])" both only dodge on "x" variable.

    The following example should reproduce the problem. It works on google colab (Seaborn version: 0.13.2) and on my local environment (Seaborn version: 0.13.0).

    Is it a known problem, is there any workaround? I tried using sequential calls to so.Dodge to no success.

    Thank you very much

    import seaborn.objects as so
    import seaborn as sns
    import matplotlib.pyplot as plt
    import pandas as pd

    # Create a small synthetic dataset
    data = pd.DataFrame({
    'day': [0, 0, 0, 0, 0,
    7, 7, 7, 7, 7,
    0,0,0,7,7],
    'type': ['Type_A', 'Type_A', 'Type_B', 'Type_B', 'Type_B',
    'Type_A', 'Type_A', 'Type_B', 'Type_B', 'Type_B',
    'Type_A', 'Type_A', 'Type_A', 'Type_A', 'Type_B'],
    'individual': ['Indiv_1', 'Indiv_2', 'Indiv_1', 'Indiv_2', 'Indiv_1',
    'Indiv_1', 'Indiv_2', 'Indiv_1', 'Indiv_2', 'Indiv_1',
    'Indiv_1', 'Indiv_2', 'Indiv_1', 'Indiv_2', 'Indiv_1'],
    'value': [5.12, 6.34, 4.87, 7.45, 5.67,
    5.67, 6.89, 4.56, 7.23, 6.12,
    5.78, 6.12, 4.98, 7.01, 5.34]
    })

    def plot_gene_day_scatter(data):
    # Map days to an evenly spaced dummy variable
    data["x"] = data["day"].map({0: 0, 7: 1})

    # Define marker mapping
    marker_map = {'Indiv_1': 'o', 'Indiv_2': 's'}

    # Create the plot
    fig, ax = plt.subplots(figsize=(12, 6))
    plot_obj = (
    so.Plot(data, x="x", y="value", color="type")
    # Add scatter points
    #HERE IS THE PROBLEM
    #The following commented line dodges on everything, including "individual, which is expected behavior
    #.add(so.Dots(pointsize=5, alpha=0.75), so.Dodge(), marker="individual")
    # What I want to do is the following line. However it only dodges on "x".
    .add(so.Dots(pointsize=5, alpha=0.75), so.Dodge(by=["x","type"]), marker="individual")
    # Scale colors and markers
    .scale(color=sns.color_palette("Set2"), marker=marker_map)
    ).on(ax)

    plot_obj.plot()
    # Customize x-axis
    ax.set_xticks(data["x"].unique())
    ax.set_xticklabels(data["day"].unique())
    return fig, ax


    # Call the function
    plot_gene_day_scatter(data)

    Continue reading...

Compartilhe esta Página