matplotlibhistogramalpha

Plotting histogram with transparent edges


I want to create a histogram using Matplotlib with both transparent facecolor and edgecolor. However, the edgecolor keyword argument doesn't seem to accept an alpha value. Am I missing something, or is edgecolor really just limited to alpha=1.0?

I want to specify the edgecolor because I am saving the figure as an SVG. Without a specified edgecolor, the SVG has small edge gaps between the bars of the histogram, despite it looking fine in the %matplotlib inline display.

#Create a histogram plot to visualize parameter distributions

def parameter_hist(dataframes, colors, parameter):

    fig, ax = plt.subplots(figsize=(10,10))
    
    for index, dataframe in enumerate(dataframes):
        color = colors[index]
        n, bins, patches = ax.hist(dataframe[parameter], bins=50, alpha=0.5, 
                                       color=color, edgecolor=color)
    
    plt.savefig(parameter+'_histogram.svg', dpi='figure')
    plt.show()
    
    return

parameter_hist([dataframe1, dataframe2, dataframe3], ['#003C86', '#00DCB5','#000000'],'gap')

I have tried providing the alpha value directly to edgecolor, ie: edgecolor=color+'80' but it appears to have no effect.


Solution

  • Due to different rounding, the borders don't occupy exactly the same spots. When saving to an SVG format, little gaps or little overlaps may occur, even when setting the linewidth of the border to 0.

    With seaborn's histogram, you can choose element='step' to only show a polygon created from the outline of the combined bars. This eliminates the gaps. Optionally, you combine it with lw=0 to also remove the outline.

    import matplotlib.pyplot as plt
    import seaborn as sns
    import pandas as pd
    import numpy as np
    
    def parameter_hist(dataframes, colors, parameter):
        fig, ax = plt.subplots(figsize=(10, 10))
    
        for color, dataframe in zip(colors, dataframes):
            sns.histplot(x=dataframe[parameter], bins=50, alpha=0.5,
                         color=color, element='step', lw=0, ax=ax)
    
        plt.savefig(parameter + '_histogram.svg', dpi='figure')
        plt.show()
        return
    
    dataframe1 = pd.DataFrame({'gap': np.random.randn(100000).cumsum()})
    dataframe2 = pd.DataFrame({'gap': np.random.randn(200000).cumsum()})
    dataframe3 = pd.DataFrame({'gap': np.random.randn(300000).cumsum()})
    parameter_hist([dataframe1, dataframe2, dataframe3], ['#003C86', '#00DCB5', '#000000'], 'gap')
    

    This is how the svg looks in Inkscape:

    svg of seaborn histogram with element='step'

    PS: Seaborn also supports element='poly', which creates a polygon out of the centers of the tops of the bars. This is how it could look like with bins=20, alpha=0.5, color=color, element='poly' (and different test data):

    element='poly'

    Depending on your data and what you want to show, you could increase or lower the number of bins. E.g. with bins=1000:

    enter image description here