dipl0
dipl0

Reputation: 1077

Set Log Scale on Matplotlib Radar Chart

I was wondering how it would be possible to plot the following graph with a yscale that is logarithmic, due to the massive difference between numbers in the 'sample' list.

ax.set_yscale('log') seems to just cause errors.

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111,polar=True)

sample = np.random.uniform(low=0.5, high=13.3, size=(15,))
sample = [35.417256011315416, 0.028288543140028287, 1.3578500707213579, 3.3663366336633667, 0.8203677510608205, 35.445544554455445, 3.3946251768033946, 19.46251768033946, 0.7072135785007072]

N = len(sample) 

theta = np.arange(0, 2*np.pi, 2*np.pi/N) 
bars = ax.bar(theta, sample, width=0.4)
#ax.set_yscale('log')
ax.set_xticks(theta)
ax.set_xticklabels(range(1, len(theta)+1))
ax.yaxis.grid(True)
plt.show()

Upvotes: 1

Views: 1702

Answers (2)

cornelius
cornelius

Reputation: 26

Just use ax.set_yscale('symlog', linthresh=0.01) or ax.set_rscale('symlog', linthresh=0.01) (is the same in a polar plot) instead of ax.set_yscale('log').

A day ago I uploaded a jupyter-notebook for more details at GitHub.

Your radar chart with symlog

Upvotes: 1

bnaecker
bnaecker

Reputation: 6440

Calling np.log10 on the data is straightforward. But this generates ticks that are in this logarithmic domain. You can transform them back into the original domain of your data by inverting the logarithm, i.e., calling 10 ** i where i is the new tick position. The key is that you're just updating the tick label. The tick itself is not moved.

The code below should do the trick:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, polar=True)

sample = np.random.uniform(low=0.5, high=13.3, size=(15,))
sample = [
    35.417256011315416,
    0.028288543140028287,
    1.3578500707213579,
    3.3663366336633667,
    0.8203677510608205,
    35.445544554455445,
    3.3946251768033946,
    19.46251768033946,
    0.7072135785007072,
]

N = len(sample)

theta = np.arange(0, 2 * np.pi, 2 * np.pi / N)
bars = ax.bar(theta, np.log10(sample), width=0.4)
ax.set_xticks(theta)
ax.set_xticklabels(range(1, len(theta) + 1))
ax.yaxis.grid(True)
precision = 2  # Change to your desired decimal precision
ax.set_yticklabels([str(round(10 ** x, precision)) for x in ax.get_yticks()])
plt.ioff()
plt.show()

This generates the following figure. Logarithmic data, with correct tick labels.

enter image description here

Upvotes: 1

Related Questions