Saya mencoba untuk memplot windrose dengan nilai konsentrasi binned. Mengikuti saran dari postingan ini, dan beberapa modifikasi, saya telah membuat plot. Namun, ada diskontinuitas di sekitar 0 derajat. Bantuan apa pun akan sangat dihargai!

Ini kode saya:

wd = list(merge_all_apr['Wind Dir (10s deg)'])
conc = list(merge_all_apr['Mean_CO2'])
ws = list(merge_all_apr['Wind Spd (km/h)'])

wd_rad = np.radians(np.array(wd))
conc = np.array(conc, dtype=np.float)

wind_speed = np.linspace(min(ws), max(ws), 16)

WD, WS = np.meshgrid(np.linspace(0, 2*np.pi, 36), wind_speed)

print (WS)

Z = interpolate.griddata((wd_rad, ws), oz, (WD, WS), method='linear')

fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
cmap = plt.get_cmap('jet')
#cmap.set_under('none')
img = ax.pcolormesh(WD, WS, Z, cmap=cmap, vmin=0, vmax=40, alpha = 0.70)
ax.set_theta_zero_location('N')
ax.set_theta_direction(-1) 
plt.colorbar(img)
plt.show()

Dan hasilnya adalah:

This image

Sebagai pencar, itu berfungsi dengan baik dan terlihat seperti

This

Saya tidak yakin bagaimana memberikan data secara ringkas, tetapi bantuan apa pun akan sangat dihargai!!

3
poolcheck 7 Juli 2020, 21:18

1 menjawab

Jawaban Terbaik

Anda juga dapat memberikan nilai untuk wd_rad hanya lebih rendah dari 0 dan lebih besar dari 2*pi menggunakan np.where, menambahkan 2*pi untuk nilai kecil dan mengurangkan 2*pi untuk nilai besar. np.tile(ws, 2) dan np.tile(conc, 2) kemudian kaitkan versi diperpanjang wd_rad dengan nilai konsentrasi yang sama. Menggunakan juga nilai-nilai yang diperluas ini di interpolate.griddata memastikan nilai konsentrasi membungkus di 0 dan 2*pi.

Sebagai tambahan, perhatikan bahwa 'jet' adalah peta warna yang terlihat bagus, tetapi sangat menyesatkan karena membuat sorotan kuning di tempat yang salah. (Juga, mengonversi kolom panda ke daftar cukup lambat dan memakan memori, lebih baik biarkan dalam format array numpy.)

Kode di bawah ini mengandaikan bahwa oz dalam pertanyaan adalah larik yang sama dengan conc.

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

# wd = merge_all_apr['Wind Dir (10s deg)']
# conc = merge_all_apr['Mean_CO2']
# ws = merge_all_apr['Wind Spd (km/h)']

N = 100
wd = np.random.uniform(0, 360, N)
conc = np.random.uniform(0, 40, N)
ws = np.random.uniform(0, 45, N)

wd_rad = np.radians(np.array(wd))
conc = np.array(conc, dtype=np.float)

wd_rad_ext = np.where(wd_rad < np.pi, wd_rad + 2 * np.pi, wd_rad - 2 * np.pi)

wind_speed = np.linspace(min(ws), max(ws), 16)

WD, WS = np.meshgrid(np.linspace(0, 2 * np.pi, 37), wind_speed)

Z = interpolate.griddata((np.hstack([wd_rad, wd_rad_ext]), np.tile(ws, 2)), np.tile(conc, 2),
                         (WD, WS), method='linear', rescale=True)

fig, axes = plt.subplots(ncols=2, figsize=(10, 4), subplot_kw={"projection": "polar"})
cmap = plt.get_cmap('magma')
for ax in axes:
    if ax == axes[0]:
        img = ax.pcolormesh(WD, WS, Z, cmap=cmap, vmin=0, vmax=40)
    else:
        img = ax.scatter(wd_rad, ws, c=conc, cmap=cmap, vmin=0, vmax=40)
    ax.set_theta_zero_location('N')
    ax.set_theta_direction(-1)
    plt.colorbar(img, ax=ax, pad=0.12)
plt.show()

example plot

Jika Anda tidak ingin interpolasi, tetapi ingin menggambar segmen dengan lebar 10 derajat untuk mewakili setiap area, plt.hist2d dapat digunakan.

Parameter khusus untuk hist2d:

  • bins=(np.linspace(0, 2 * np.pi, 37), np.linspace(min(ws), max(ws), 17)): arah angin akan dibagi menjadi 36 wilayah (37 batas); kecepatan akan dibagi menjadi 16 wilayah
  • weights=conc: alih-alih histogram biasa yang menghitung jumlah nilai ke setiap wilayah kecil, gunakan konsentrasi; ketika beberapa konsentrasi diukur di wilayah kecil yang sama, mereka dirata-rata
  • cmin=0.001: biarkan daerah kosong ketika nilai konsentrasinya kurang dari 0.001
  • cmap = 'magma_r': gunakan peta warna 'magma' terbalik, sehingga nilai tinggi menjadi gelap dan nilai rendah mendapatkan warna terang (lihat dokumen tentang peta warna lain yang mungkin lebih cocok untuk mengilustrasikan data, tetapi cobalah untuk tidak menggunakan 'jet')

Nilai kembalian hist2d adalah matriks nilai histogram, batas bin (x dan y) dan kumpulan patch berwarna (yang dapat digunakan sebagai input untuk peta warna).

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

N = 100
wd = np.random.uniform(0, 360, N)
conc = np.random.uniform(0, 40, N)
ws = np.random.uniform(0, 45, N)

wd_rad = np.radians(np.array(wd))
conc = np.array(conc, dtype=np.float)

fig, axes = plt.subplots(ncols=2, figsize=(10, 4), subplot_kw={"projection": "polar"})
cmap = 'magma_r'
for ax in axes:
    if ax == axes[0]:
        _, _, _, img = ax.hist2d(wd_rad, ws, bins=(np.linspace(0, 2 * np.pi, 37), np.linspace(min(ws), max(ws), 17)),
                                 weights=conc, cmin=0.001, cmap=cmap, vmin=0, vmax=40)
    else:
        img = ax.scatter(wd_rad, ws, c=conc, cmap=cmap, vmin=0, vmax=40)
    ax.set_theta_zero_location('N')
    ax.set_theta_direction(-1)
    plt.colorbar(img, ax=ax, pad=0.12)
plt.show()

hist2d plot

1
JohanC 8 Juli 2020, 18:03