'Python polar bar chart - Remove degrees & color one ring

I have been trying to create a polar bar chart in python for quite some time. After some research I managed to get the results that I wanted. Well, almost. There're still a couple thing that I don't know how to do.

I include my code:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FixedLocator
from operator import add

#DATA MANIPULATION
dataset = pd.read_csv('Controls.csv', delimiter=";")
dataset.astype({'Rating':'float'})
#print(dataset.dtypes)

categories = dataset['Category'].drop_duplicates()
controls = dataset['Control'].drop_duplicates()

categ_avg = []
control_average = []

#Average for controls
for category in categories:
       avg = 0
       for index, item in dataset.iterrows():
              if item['Category'] == category:
                     avg += item['Rating']
       categ_avg.append(avg)
       avg = 0

for control in controls:
    avg = 0
    for index, item in dataset.iterrows():
        if item['Control'] == control:
            avg += item['Rating']
    control_average.append(avg)
    avg = 0

average = [total / 5 for total in categ_avg]

avgdf = pd.DataFrame({
       'Category' : categories,
       #'Controls' : controls,
       'Average' : average
})

#PLOTTING
#Compute pie slices which is the number of unique controls
N = len(controls)

#theta = np.linspace(0, 2 * np.pi, N, endpoint=False)
theta = [0]
for cat in categories:
    if cat == 'CAT-A':
            theta.append( theta[-1] + (2 * np.pi/N * 2) )
    else:
            theta.append( theta[-1] + (2*np.pi / N) )
print(theta)

#Compute the filling axis
mid_theta = []
for cat in categories:
    if cat == 'CAT-A':
            mid_theta.append( 2 * np.pi/N )
    else:
            mid_theta.append( 2 * np.pi / N / 2 )
mid_theta = list(map(add,theta, mid_theta))
print(mid_theta)
radii = avgdf['Average']
#width = theta[1] - theta[0]
width = []
for i in range(0, len(avgdf['Average'])):
       width.append(theta[i+1] - theta[i])

fig = plt.figure()
fig.patch.set_facecolor('white')
fig.patch.set_alpha(0.5)

#Draw X labels
ax = fig.add_subplot(111, projection='polar')
ax.set_xticks(theta)

# Draw ylabels
ax.set_rlabel_position(0)
ax.set_yticks([1, 2, 3, 4, 5])
ax.set_yticklabels(["1", "2", "3", "4", "5"], color="black", size=8)
ax.set_ylim(0, 5)

#colors = plt.cm.hsv(theta/2/np.pi)

bars = ax.bar(mid_theta, radii, width=width, bottom=0.0)

#Labels
for bar, angle, label in zip(bars, mid_theta, avgdf["Category"]):

    # Labels are rotated. Rotation must be specified in degrees :(
    rotation = np.rad2deg(angle)

    # Flip some labels upside down
    alignment = ""
    if angle >= np.pi/2 and angle < 3*np.pi/2:
        alignment = "right"
        rotation = rotation + 180
    else: 
        alignment = "left"

    # Finally add the labels
    ax.text(
        x=angle, 
        y=5.5,
        s=label, 
        ha=alignment, 
        va='center') 


#Use custom colors and opacity
for r, bar in zip(avgdf['Average'], bars):
    bar.set_facecolor(plt.cm.viridis(r/5.))
    bar.set_alpha(0.5)

plt.show()

When I execute it I obtain the following graph: Resulting graph

What I'm trying to achieve is:

  • I would like to color the ring number 4 in green.
  • I would like to remove the degrees from the outer ring. I only want to see my categories not the 0, 144º...

I really appreciate the help.

Thanks you.



Solution 1:[1]

Create a list of colours with as many colours as you have polar bars.

c = ['blue', 'blue', 'blue', 'green', 'blue', 'blue']

bars = ax.bar( x=angles, height=heights, width=width, color=c, linewidth=2, edgecolor="white")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TimothyAURA