Search code examples
pythonmatplotlibnlpdata-visualizationtopic-modeling

matplotlib visualization- positive negative proportion chart


I'm trying to make the same chart as below and wonder if matplotlib has a similar chart to make that.

The chart below is the result of the STM topic model in the R package

I have probs values using DMR in Python:

array([[0.07204196, 0.04238116],
       [0.04518877, 0.30546978],
       [0.0587892 , 0.19870868],
       [0.16710107, 0.07182639],
       [0.128209  , 0.02422131],
       [0.15264449, 0.07237352],
       [0.2250081 , 0.06986096],
       [0.1337716 , 0.10750801],
       [0.01197221, 0.06736039],
       [0.00527367, 0.04028973]], dtype=float32)

These are the results and left is Negative words and right is Positive

Example of negative positive proportion chart:

Example of negative positive proportion chart


Solution

  • It is possible to create something quite close to the image you included. I understood that the right column should be negative while the right column should be positive?

    First make the data negative:

    import numpy as np
    
    arr = np.array([[0.07204196, 0.04238116],
                    [0.04518877, 0.30546978],
                    [0.0587892 , 0.19870868],
                    [0.16710107, 0.07182639],
                    [0.128209  , 0.02422131],
                    [0.15264449, 0.07237352],
                    [0.2250081 , 0.06986096],
                    [0.1337716 , 0.10750801],
                    [0.01197221, 0.06736039],
                    [0.00527367, 0.04028973]], dtype="float32")
    
    # Make the right col negative
    arr[:, 0] *= -1
    

    Then we can plot like so:

    from string import ascii_lowercase
    import matplotlib.pyplot as plt
    
    
    fig, ax = plt.subplots()
    
    for y, x in enumerate(arr.flatten()):
        # Get a label from the alphabet
        label = ascii_lowercase[y]
        # Plot the point
        ax.plot(x, y, "o", color="black")
        # Annotate the point with the label
        ax.annotate(label, xy=(x, y), xytext=(x - 0.036, y), verticalalignment="center")
    
    # Add the vertical line at zero
    ax.axvline(0, ls="--", color="black", lw=1.25)
    
    # Make the x axis equal
    xlim = abs(max(ax.get_xlim(), key=abs))
    ax.set_xlim((-xlim, xlim))
    
    # Remove y axis
    ax.yaxis.set_visible(False)
    
    # Add two text labels for the x axis
    for text, x in zip(["Negative", "Positive"], ax.get_xlim()):
        ax.text(x / 2, -3.75, f"{text} Reviews", horizontalalignment="center")
    

    Which outputs:

    Chart with annotated points

    You can tweak the values in the calls to ax.annotate and ax.text if you need to change the locations of the text on the plot or x-axis.