3

I need to color a circular histogram with color that corresponds to the angle.

I found an example in matplotlib library that colors a polar scatterplot in the way that I need: https://matplotlib.org/examples/pie_and_polar_charts/polar_scatter_demo.html

But this is a scatterplot, and I need a circular histogram, and I use the code from the response to this question: Circular Histogram for Python

I want to be able to change so that the bars have the colors from the first image. But the ax.bar doesn't take a string color as a scatterplot does, returning an error.

Here is the code for the circular histogram:

import numpy as np
import matplotlib.pyplot as plt 

N = 80
bottom = 8
max_height = 4

theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = max_height*np.random.rand(N)
width = (2*np.pi) / N

ax = plt.subplot(111, polar=True)
bars = ax.bar(theta, radii, width=width, bottom=bottom)

# Use custom colors and opacity
for r, bar in zip(radii, bars):
    bar.set_facecolor(plt.cm.jet(r / 10.))
    bar.set_alpha(0.8)

plt.show()

Edit: substituting radii for theta in the last part of the plot changes the colors of the bars, but doesn't produce the color scheme in which the colors change continuously over the whole range of the circle. I tried normalising theta in degrees and radians as proposed in the comments:

bar.set_facecolor(math.degrees(r)/360))

and

bar.set_facecolor(plt.cm.jet(r/2*np.pi))

Both of which produce the wrong solution.

Sanya Pushkar
  • 180
  • 1
  • 16
  • Currently the histogram bars are colored according to their radius (`radii` in the code). Now you want it to be colored according to the angle (`theta` in the code). Big quizmaster question: Which variable do you need to replace in order for that to happen? – ImportanceOfBeingErnest Feb 08 '19 at 20:34
  • Thanks, that makes sense, to just substitute radii for theta in the code in the custom color part. But that doesn't produce the colors I need (specifically it doesn't close the color loop). I tried a different normalisation constant, but failed. – Sanya Pushkar Feb 08 '19 at 20:37
  • What is this factor 10? `theta` is in radians. Did you try converting them to degrees? – Sheldore Feb 08 '19 at 20:40
  • A full circle comprises 2π. So instead of 10 divide by 2π. I guess you can still update your question in case you face a problem doing so, but currently it's not obvious what would fail. – ImportanceOfBeingErnest Feb 08 '19 at 20:41
  • @ImportanceOfBeingErnest Thank you, I tried both radians and degrees, but both produce discontinuity in colors at 0 degrees (which the scatterplot doesn't have). I will update the question – Sanya Pushkar Feb 08 '19 at 20:48
  • You are using the `jet` colormap. The example you quote uses the `hsv` colormap. Also note that `r/2*np.pi` is not the same as `r/(2*np.pi)`. – ImportanceOfBeingErnest Feb 08 '19 at 20:59

2 Answers2

4

It looks like the example would need some overhaul. It can be simplified as follows, where the two requested changes from the question are:

  1. Use a different colormap (here hsv).
  2. Encode the angle (theta) instead of the radius (radii) into color.

No loop is needed for that.

import numpy as np
import matplotlib.pyplot as plt

# Fixing random state for reproducibility
np.random.seed(19680801)

# Compute pie slices
N = 20
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = 10 * np.random.rand(N)
width = 2 * np.pi / N
colors = plt.cm.hsv(theta/2/np.pi)

ax = plt.subplot(111, projection='polar')
bars = ax.bar(theta, radii, width=width, bottom=4, color=colors)

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
0

I converted radians to degrees and divided by 360. To convert radians to degrees, I use math.degrees().

import math

# Use custom colors and opacity
for th, bar in zip(theta, bars):
    bar.set_facecolor(plt.cm.hsv(math.degrees(th)/360))
    bar.set_alpha(0.8)

EDIT As I mentioned in the comments, the example you provided uses hsv color map and not the jet as your were using. Answer updated.

enter image description here

Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • Thank you! I can't have images in my question because I don't have enough 'reputation'. But I did produce the same result, and it has a discontinuity at 0, that the scatterplot doesn't have. – Sanya Pushkar Feb 08 '19 at 20:50
  • Can you perhaps explain what you mean by discontinuity at 0 degree? – Sheldore Feb 08 '19 at 20:53
  • The color changes from dark red to dark blue at 0. actually if you open the scatterplot link you can see the colors are different (between red and blue there is pink for example) – Sanya Pushkar Feb 08 '19 at 20:57
  • @Sanya: Yes, that's because the scatter plot example uses `hsv` color map whereas you are using `jet` which starts and ends at red and blue. If you replace `jet` by `hsv` in my answer, you will get the same result as in the scatter plot without any discontinuity – Sheldore Feb 08 '19 at 20:58
  • @Sanya: I did that just now – Sheldore Feb 08 '19 at 21:03