Search code examples
pythonplotlyprocess-mining

How to plot bupar Precedence Matrix using Plotly in Python?


I'm trying to plot a bupar Precedence Matrix as below using Plotly.

enter image description here

So far I tried to plot a scatter plot as below:

import plotly.express as px

fig = px.scatter(df, 
                 y="Antecedent", 
                 x="Consequent", 
                 size="Absolute_Frequency", 
                 color="Absolute_Frequency")

fig.update_traces(
    hovertemplate="<br>".join([
        "Antecedent: %{y}",
        "Consequent: %{x}"
    ]),
    name=""
)

fig.update_layout(
    template="plotly_white",
    # Figure title styling
    title= dict(
        text="Precedence Matrix",
        x=0.5,
        y=0.95,
        font=dict(
            family="Rockwell",
            size=20,
            color='#000000'
            )
        ),
    xaxis_title="Consequent",
    yaxis_title="Antecedent",
    font=dict(
        family="Rockwell",
        size=16),
    # Fig height
    height=600, 
    width=1200,
    # Turn off legend
    showlegend=False,
    hoverlabel=dict(
        bgcolor="white",
        font_size=16,
        font_family="Rockwell"
        )
    )

fig.show()

How to add the text annotations and create rectangles in plotly as per the bupar Precedence Matrix?

enter image description here

Data Prep

Antecedent Consequent Absolute_Frequency
register request examine thoroughly 1
examine thoroughly check ticket 2
check ticket decide 6
decide reject request 3
register request check ticket 2
check ticket examine casually 2
examine casually decide 2
decide pay compensation 3
register request examine casually 3
examine casually check ticket 4
decide reinitiate request 3
reinitiate request examine thoroughly 1
check ticket examine thoroughly 1
examine thoroughly decide 1
reinitiate request check ticket 1
reinitiate request examine casually 1

Solution

  • You are close: if you add the argument text="Absolute_Frequency" to px.scatter, and then update the traces: fig.update_traces(marker={'symbol': 'square'}, textfont_color='white', textposition='middle center') this should hopefully give you the desired chart.

    Comment: I notice that in the original chart, the markers are all the same size. In the code you included, the markers are sized depending on their absolute frequency, meaning that the text is sometimes larger than the marker. If you want the markers to all be the same size, you can remove the argument size="Absolute_Frequency"

    fig = px.scatter(df, 
                     y="Antecedent", 
                     x="Consequent", 
                     size="Absolute_Frequency", 
                     color="Absolute_Frequency",
                     text="Absolute_Frequency"
                     )
    
    fig.update_traces(
        hovertemplate="<br>".join([
            "Antecedent: %{y}",
            "Consequent: %{x}"
        ]),
        name=""
    )
    
    fig.update_layout(
        template="plotly_white",
        # Figure title styling
        title= dict(
            text="Precedence Matrix",
            x=0.5,
            y=0.95,
            font=dict(
                family="Rockwell",
                size=20,
                color='#000000'
                )
            ),
        xaxis_title="Consequent",
        yaxis_title="Antecedent",
        font=dict(
            family="Rockwell",
            size=16),
        # Fig height
        height=600, 
        width=1200,
        # Turn off legend
        showlegend=False,
        hoverlabel=dict(
            bgcolor="white",
            font_size=16,
            font_family="Rockwell"
            )
        )
    
    fig.update_traces(marker={'symbol': 'square'}, textfont_color='white', textposition='middle center')
    fig.show()
    

    enter image description here

    EDIT: after you remove the argument size="Absolute_Frequency", you can change the marker size and set the font size to get something closer to the image you showed originally.

    fig = px.scatter(df, 
                     y="Antecedent", 
                     x="Consequent", 
                     # size="Absolute_Frequency", 
                     color="Absolute_Frequency",
                     text="Absolute_Frequency"
                     )
    
    fig.update_traces(
        hovertemplate="<br>".join([
            "Antecedent: %{y}",
            "Consequent: %{x}"
        ]),
        name=""
    )
    
    fig.update_layout(
        template="plotly_white",
        # Figure title styling
        title= dict(
            text="Precedence Matrix",
            x=0.5,
            y=0.95,
            font=dict(
                family="Rockwell",
                size=20,
                color='#000000'
                )
            ),
        xaxis_title="Consequent",
        yaxis_title="Antecedent",
        font=dict(
            family="Rockwell",
            size=16),
        # Fig height
        height=600, 
        width=1200,
        # Turn off legend
        showlegend=False,
        hoverlabel=dict(
            bgcolor="white",
            font_size=16,
            font_family="Rockwell"
            )
        )
    
    fig.update_traces(
        marker={'symbol': 'square', 'size': 50}, 
        textfont_color='white', 
        textfont_size=14,
        textposition='middle center'
    )
    fig.show()
    

    enter image description here