0

I am trying to recreate the contour plot shown below in Matplotlib, using the following code to generate the data:

theta = np.arange(math.radians(0), math.radians(361),0.01).tolist() # initialise theta values
g4 = []
for i in theta:
    v = ((2**(1-1)) * (1 + (1*math.cos(i)))**1) # equation to generate the data
g4.append(v)

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.scatter(theta, g4, c=g4, cmap='viridis')

enter image description here

So far, I have been able to generate a scatter plot using this data which looks as follows:

enter image description here

However I am completely unsure of how to convert my data into the correct form to produce the required scatter plot, I have tried:

ax.contourf(theta, g4, g4)

But I get TypeError: Input z must be 2D, not 1D

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Dragmoogle
  • 61
  • 7
  • Take a look at https://stackoverflow.com/questions/9071084/polar-contour-plot-in-matplotlib-best-modern-way-to-do-it and see if it helps. You'll need to create a grid over values to use `contourf``. – Matt Pitkin May 24 '23 at 13:32
  • Unfortunately I cannot figure out how to apply that answer to my case, I have tried using the meshgrid function but it gives me a contour plot that covers the entire polar plot. I am just looking for it to cover the part of the plot that is inside of the current scatter plot, sort of a fill_between but which also includes a gradient of colours – Dragmoogle May 24 '23 at 13:53

1 Answers1

3

Based on the answer here, you could do:

azimuths = np.radians(np.linspace(0, 360, 50))
zeniths = np.linspace(0, 4, 50)

r, theta = np.meshgrid(zeniths, azimuths)

f = 1 + np.cos(theta)  # your function is essentially this

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})

ax.contourf(theta, r, f)

which produces:

enter image description here

This obviously doesn't look like the example plot that you show, but that's because your function is only a function of theta and not of r. So, it is therefore constant in the radial direction for any value of theta.

To get something similar to the example plot, you could add the r variable in to the function, e.g.:

azimuths = np.radians(np.linspace(0, 360, 250))
zeniths = np.linspace(0, 4, 250)

r, theta = np.meshgrid(zeniths, azimuths)

# function that also depends on r
f = 1 + np.cos(theta) - (0.35 * r)**2

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})

f[f <= 0] = np.inf  # mask out values that are negative

ax.grid()
ax.pcolormesh(theta, r, f, cmap="viridis_r")  # plot function
ax.grid(True)
ax.contour(theta, r, f, levels=10, colors="k", linewidths=0.25)  # add contours
ax.set_rticks([0, 1, 2, 3, 4]);  # set radial tick values

enter image description here

Matt Pitkin
  • 3,989
  • 1
  • 18
  • 32