Search code examples
pythonmatplotlibz-orderwindrose

'zorder' is not working properly in a windrose diagram


Windrose Diagram

I have set a higher zorder value for the bar plot compared to gridlines. But the gridlines are still visible over the bars. I have also tried for 'ax.set_axisbelow(True)' which is not working. Can anyone explain me how to solve the issue ?

from windrose import WindroseAxes
import pandas as pd
import matplotlib.pyplot as plt

# Sample data
data = {
    'WD (Deg)': [45, 90, 135, 180, 225, 270, 315, 0, 45],
    'WS (m/s)': [2, 3, 4, 5, 6, 7, 8, 9, 10]}

# Create a DataFrame
df = pd.DataFrame(data)

# Create a WindroseAxes object
ax = WindroseAxes.from_ax()

# Customize the grid
ax.grid(True, linestyle='--', linewidth=2.0, alpha=0.5,
        color='grey', zorder = 0)

# Set the axis below the wind rose bars
ax.set_axisbelow(True) ## Not working 

# Plot the wind rose bars
ax.bar(df['WD (Deg)'], df['WS (m/s)'], normed=True, opening=0.5, edgecolor='black',
       cmap=plt.cm.jet, zorder = 3)

plt.show()

I don't understand why is it happening. I want to plot the gridlines below the barplots. Thank in advance.


Solution

  • You can manually set the zorder of the patches, for example:

    from windrose import WindroseAxes
    import pandas as pd
    import matplotlib.pyplot as plt
    
    # Sample data
    data = {
        'WD (Deg)': [45, 90, 135, 180, 225, 270, 315, 0, 45],
        'WS (m/s)': [2, 3, 4, 5, 6, 7, 8, 9, 10]}
    
    # Create a DataFrame
    df = pd.DataFrame(data)
    
    # Create a WindroseAxes object
    ax = WindroseAxes.from_ax()
    
    # Customize the grid
    ax.grid(True, linestyle='--', linewidth=2.0, alpha=0.5,
            color='grey', zorder=0)
    
    # Set the axis below the wind rose bars
    ax.set_axisbelow(True) ## Not working 
    
    # Plot the wind rose bars
    ax.bar(df['WD (Deg)'], df['WS (m/s)'], normed=True, opening=0.5, edgecolor='black',
           cmap=plt.cm.jet)
    
    
    from matplotlib.patches import Rectangle
    
    # get the minimum zorder of the patches
    minzorder = min(
        [
            c.get_zorder() for c in ax.get_children() if isinstance(c, Rectangle)
        ]
    )
    
    # loop through rectangle patches and set zorder manually
    # (keeping relative order of each rectangle and adding 3)
    for child in ax.get_children():
        if isinstance(child, Rectangle):
            zorder = child.get_zorder()
            child.set_zorder(3 + (zorder - minzorder))
    
            # or just subtract ZBASE, e.g.
            # from windrose.windrose import ZBASE
            # child.set_zorder(3 + (zorder - ZBASE))
    
    plt.show()
    

    enter image description here