Search code examples
pythonsortingplotlyplotly-express

In Plotly Express Funnel how do you re-order de y-axis categories?


I have a DataFrame with all my data and i have the following stage order

order = {0:'NEW',1:'FOLLOW_UP',2:'Demo',3:'QUOTE',4:'CLOSING'}
fig = px.funnel(df, x='count', y='name', color='source',category_orders=order)

My DataFrame is perfectly in desired Order as the Order dictionary, but my graph keeps switching positions with QUOTE and DEMO.

It actually makes no difference if category_orders is used or not, tried a bunch of dictionaries styles and arranges but none seem to work.

https://plotly.com/python-api-reference/generated/plotly.express.funnel.html category_orders (dict with str keys and list of str values (default {})) – By default, in Python 3.6+, the order of categorical values in axes, legends and facets depends on the order in which these values are first encountered in data_frame (and no order is guaranteed by default in Python below 3.6). This parameter is used to force a specific ordering of values per column. The keys of this dict should correspond to column names, and the values should be lists of strings corresponding to the specific display order desired.

Here is the DataFrame with the issue at the Bottom with Demo and QUOTE

Check the image of my funnel here Funnel with wrong order by plotly


Solution

  • In my opinion the issues is caused by the difference how Ploty expects the input data to look like and how your dataframe looks.

    Funnel plots seem to expect that all categories present at the end of the funnel are present at each previous stage. Your Closing source is not present QUOTE and your value from QUOTE is missing in Demo. If you add these two values the order should be correct.

    import plotly.express as px
    import pandas as pd
    import io
    
    data = '''count name    source
    0   NEW IG
    2   NEW 0
    1   NEW GCLID
    1   NEW UTM
    1   NEW UTM
    1   NEW GCLID
    1   NEW GLCID
    7   NEW UTM
    1   NEW GLCID
    1   NEW GCLID
    2   NEW 123
    1   NEW GCLID
    1   NEW GCLID
    1   NEW FB
    1   NEW FBCLID
    1   NEW UTM
    1   NEW UTM
    1   NEW DATA
    1   NEW R
    1   NEW GCLID
    11  NEW FB
    1   NEW FB
    7   NEW FB
    1   NEW FB
    1   NEW GCLID
    1   NEW GCLID
    1   NEW GCLID
    1   FOLLOW_UP   FB
    2   FOLLOW_UP   FB
    1   FOLLOW_UP   0
    1   FOLLOW_UP   IG
    1   FOLLOW_UP   FB
    1   FOLLOW_UP   FB
    1   FOLLOW_UP   FB
    2   FOLLOW_UP   123
    3   DEMO    FB
    1   QUOTE   123
    1   QUOTE   123
    2   QUOTE   123
    3   CLOSING FB'''.splitlines()
    
    df = pd.read_csv(io.StringIO('\n'.join(data)), sep='\t')
    px.funnel(df, x='count', y='name', color='source')
    
    # incorrect order
    

    enter image description here # correct order

    data.insert(-5, '0\tDEMO\t123')
    data.insert(-2, '0\tQUOTE\tFB')
    df = pd.read_csv(io.StringIO('\n'.join(data)), sep='\t')
    px.funnel(df, x='count', y='name', color='source')
    

    enter image description here