1

I am trying to create a pollution rose plot as described in the link Plotting Windrose: making a pollution rose with concentration set to color

Example in the reply is working but when I used my data then it is giving a weird plot. Any advice where I am going wrong? Thank you.

import matplotlib.pyplot as plt
import numpy as np

wd = [90.,297.,309.,336.,20.,2.,334.,327.,117.,125.,122.,97.,95.,97.,103.,106.,125.,148.,147.,140.,141.,145.,144.,151.,161.]
ws = [15,1.6,1.8,1.7,2.1,1.6,2.1,1.4,3,6.5,7.1,8.2,10.2,10.2,10.8,10.2,11.4,9.7,8.6,7.1,6.4,5.5,5,5,6]
oz = [10.,20.,30.,40.,50.,60.,70.,80.,90.,100.,110.,120.,90.,140.,100.,106.,125.,148.,147.,140.,141.,145.,144.,151.,161.]

pi_fac = 22/(7*180.)
wd_rad = [w * pi_fac for w in wd]
ws_r = np.linspace(min(ws),max(ws),16)

WD,WS = np.meshgrid(wd_rad,ws_r) 
C = oz + np.zeros((len(ws_r),len(wd)),dtype=float)
C = np.ma.masked_less_equal(C,10)

fig, ax = plt.subplots(subplot_kw={"projection":"polar"})
ax.pcolormesh(WD,WS,C,vmin=10, vmax=170) # I tried different vmin and vmax too

plt.show()

Pic with error

JohanC
  • 71,591
  • 8
  • 33
  • 66
RajanK
  • 11
  • 2
  • Could you paste the code that is working and include a picture of the weird plot you're getting? – peer May 09 '20 at 21:15

1 Answers1

2

The linked post assumes you have a regular grid for directions and for speeds, but your input seems to be quite unordered combinations.

To create a plot with colored regions depending on the oz values, you could try tricontourf. tricontourf takes in X, Y and Z values that don't need to lie on a grid and creates a contour plot. Although it is meant for rectangular layouts, it might also work for your case. It will have a discontinuity though, when crossing from 360º to 0º.

The plot of this example also draws a colorbar to show which range of oz values correspond to which color. vmin and vmax can change this mapping of colors.

import matplotlib.pyplot as plt
import numpy as np

wd = [90, 297, 309, 336, 20, 2, 334, 327, 117, 125, 122, 97, 95, 97, 103, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]
ws = [15, 1.6, 1.8, 1.7, 2.1, 1.6, 2.1, 1.4, 3, 6.5, 7.1, 8.2, 10.2, 10.2, 10.8, 10.2, 11.4, 9.7, 8.6, 7.1, 6.4, 5.5, 5, 5, 6]
oz = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 90, 140, 100, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]

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

cont = ax.tricontourf(np.radians(np.array(wd)), ws, oz, cmap='hot')
plt.colorbar(cont)
plt.show()

demo plot

With ax.scatter(np.radians(np.array(wd)), ws, c=oz, cmap='hot', vmax=250) you could create a scatter plot to get an idea how the input looks like when colored.

You might want to incorporate Python's windrose library to get polar plots to resemble a windrose.

Another approach, which might be closer to the one intended by the linked question, would be to use scipy's interpolate.griddata to map the data to a grid. To get rid of the areas without data, an 'under' color of 'none' can be used, provided that vmin is higher than zero.

import matplotlib.pyplot as plt
import numpy as np
from scipy import interpolate

wd = [90, 297, 309, 336, 20, 2, 334, 327, 117, 125, 122, 97, 95, 97, 103, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]
ws = [15, 1.6, 1.8, 1.7, 2.1, 1.6, 2.1, 1.4, 3, 6.5, 7.1, 8.2, 10.2, 10.2, 10.8, 10.2, 11.4, 9.7, 8.6, 7.1, 6.4, 5.5, 5, 5, 6]
oz = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 90, 140, 100, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]
wd_rad = np.radians(np.array(wd))
oz = np.array(oz, dtype=np.float)


WD, WS = np.meshgrid(np.linspace(0, 2*np.pi, 36), np.linspace(min(ws), max(ws), 16 ))
Z = interpolate.griddata((wd_rad, ws), oz, (WD, WS), method='linear')

fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
cmap = plt.get_cmap('hot')
cmap.set_under('none')
img = ax.pcolormesh(WD, WS, Z, cmap=cmap, vmin=20)
plt.colorbar(img)
plt.show()

gridded plot

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • If this answers your question, you might consider [marking](https://stackoverflow.com/help/someone-answer) it as accepted. – JohanC Jul 07 '20 at 21:15