AHerdofSeaCows
AHerdofSeaCows

Reputation: 227

How can I turn my DataFrame into a Radar Chart using Python?

I have a DataFrame I want to turn into a Radar Chart. The DataFrame looks like this when it's ran...

╔═══════════════════╗
║ Col A      Col B  ║
╠═══════════════════╣
║ Home       6.797  ║
║ Other      3.243  ║
║ Used       12.567 ║
║ New        8.985  ║
║ Service    1.345  ║
╚═══════════════════╝

I repurposed some code I found on another Stack Overflow question pertaining to Pandas and Radar Charts and it works for the most part except I can't get the values of Col B to align properly within the chart. Below is the code I'm using...

df['Z'] = np.ones(len(df))
points = mergedFrame.pivot_table(values='Z', index=['Col A'], columns=['Col B'])
fig = plt.figure()
ax = fig.add_subplot(111, projection="polar")

theta = np.arange(len(points))/float(len(points))*2.*np.pi
l1, = ax.plot(theta, color="C2", marker="o", label="Name of Col B")

def _closeline(line):
    x, y = line.get_data()
    x = np.concatenate((x, [x[0]]))
    y = np.concatenate((y, [y[0]]))
    line.set_data(x, y)
[_closeline(l) for l in [l1]]

ax.set_xticks(radar)
ax.set_xticklabels(points.index)
plt.legend()
plt.title("Title")
plt.show()

And the chart looks like this...

enter image description here

Since I'm still such a newbie at Python I have no idea what I'm doing wrong here. I've tried many things to modify the code including eliminating the first two lines of code and simply putting... points = df['Col B'] instead but all it did was erase the names around the circle while leaving everything else the same. What am I doing wrong here?

Also how can I fill the area inside the theta with a light green? I tried l1, = ax.fill(theta, facecolor = 'g', alpha=0.25) below the l1, = ax.plot(theta, color="C2", marker="o", label="Name of Col B") line, but it gave me this error AttributeError: 'Polygon' object has no attribute 'get_data' and I can't seem to work it out.

Any help is much appreciated!

Upvotes: 6

Views: 9418

Answers (2)

Vially KM
Vially KM

Reputation: 181

I know the problem has been solved previously, however, I would like to share also another approach which looks easier and can be helpful for anyone who is looking for a more simple way.

Another easy and efficient way to do it is using plotly which very simple, easy and fast compared to matplotlib. For the same problem plotly works 9 to 10 times faster than matplotlib.

Step1: Install plotly:

pip install plotly

Step2:

import plotly.express as px
import time
t1 = time.time()
df00 = pd.DataFrame({'Col A': ['home', 'other', 'used', 'new', 'service'],
                   'Col B': [6.797, 3.243, 12.567, 8.985, 1.345]})
fig = px.line_polar(df00, r='Col B', theta='Col A', line_close=True)
fig.show()
t2 = time.time()
print(t2-t1)

enter image description here For more details, refer to the following link https://plotly.com/python/radar-chart/

Upvotes: 2

JohanC
JohanC

Reputation: 80409

Here is an adaption of the code at this example to get you started with the way your data is stored.

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

df = pd.DataFrame({'Col A': ['home', 'other', 'used', 'new', 'service'],
                   'Col B': [6.797, 3.243, 12.567, 8.985, 1.345]})
fig = plt.figure()
ax = fig.add_subplot(111, projection="polar")

# theta has 5 different angles, and the first one repeated
theta = np.arange(len(df) + 1) / float(len(df)) * 2 * np.pi
# values has the 5 values from 'Col B', with the first element repeated
values = df['Col B'].values
values = np.append(values, values[0])

# draw the polygon and the mark the points for each angle/value combination
l1, = ax.plot(theta, values, color="C2", marker="o", label="Name of Col B")
plt.xticks(theta[:-1], df['Col A'], color='grey', size=12)
ax.tick_params(pad=10) # to increase the distance of the labels to the plot
# fill the area of the polygon with green and some transparency
ax.fill(theta, values, 'green', alpha=0.1)

# plt.legend() # shows the legend, using the label of the line plot (useful when there is more than 1 polygon)
plt.title("Title")
plt.show()

resulting radar plot

Upvotes: 7

Related Questions