数据表中的径向热图

2024-04-28 15:11:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含3列数据的文件:天顶(Z,从0到90°)和方位(a,从0到360°)。和亮度作为颜色变量

我需要将python与matplotlib结合使用,将这些数据绘制成类似以下内容: annual irradiation

这是到目前为止我的代码(它返回一个错误):

import matplotlib.pyplot as plt
import numpy as np

# `data` has the following shape:
# [
#    [Zenith value going from 0 to 90],
#    [Azimuth values (0 to 365) increasing by 1 and looping back after 365],
#    [radiance: floats that need to be mapped by the color value]
#]
data = [[6.000e+00 1.200e+01 1.700e+01 2.300e+01 2.800e+01 3.400e+01 3.900e+01
  4.500e+01 5.000e+01 5.600e+01 6.200e+01 6.700e+01 7.300e+01 7.800e+01
  8.400e+01 8.900e+01 3.934e+01 4.004e+01 4.054e+01 4.114e+01 4.154e+01
  4.204e+01 4.254e+01 4.294e+01 4.334e+01 4.374e+01 4.414e+01 4.454e+01
  4.494e+01 4.534e+01 4.564e+01 4.604e+01 4.644e+01 4.684e+01 4.714e+01
  4.754e+01 4.794e+01 4.824e+01 4.864e+01 4.904e+01 4.944e+01 4.984e+01
  5.014e+01 5.054e+01 5.094e+01 5.134e+01 5.174e+01 5.214e+01 5.264e+01
  5.304e+01 5.344e+01 5.394e+01 5.444e+01 5.494e+01 5.544e+01 5.604e+01
  5.674e+01 5.764e+01]
 [1.960e+02 3.600e+01 2.360e+02 7.600e+01 2.760e+02 1.160e+02 3.160e+02
  1.560e+02 3.560e+02 1.960e+02 3.600e+01 2.360e+02 7.600e+01 2.760e+02
  1.160e+02 3.160e+02 6.500e+00 3.400e+00 3.588e+02 2.500e+00 3.594e+02
  3.509e+02 5.000e-01 6.900e+00 1.090e+01 3.478e+02 1.250e+01 1.050e+01
  7.300e+00 2.700e+00 3.571e+02 3.507e+02 1.060e+01 3.200e+00 3.556e+02
  3.480e+02 7.300e+00 3.597e+02 3.527e+02 1.260e+01 6.600e+00 1.200e+00
  3.570e+02 3.538e+02 3.520e+02 3.516e+02 3.528e+02 3.560e+02 1.200e+00
  8.800e+00 3.567e+02 1.030e+01 6.800e+00 8.300e+00 3.583e+02 3.581e+02
  3.568e+02 3.589e+02]
 [3.580e-04 6.100e-04 3.220e-04 4.850e-04 4.360e-04 2.910e-04 1.120e-03
  2.320e-04 4.300e-03 2.680e-04 1.700e-03 3.790e-04 7.460e-04 8.190e-04
  1.030e-03 3.650e-03 3.050e-03 3.240e-03 3.340e-03 3.410e-03 3.490e-03
  3.290e-03 3.630e-03 3.510e-03 3.320e-03 3.270e-03 3.280e-03 3.470e-03
  3.720e-03 3.960e-03 3.980e-03 3.700e-03 3.630e-03 4.100e-03 4.080e-03
  3.600e-03 3.990e-03 4.530e-03 4.040e-03 3.630e-03 4.130e-03 4.370e-03
  4.340e-03 4.210e-03 4.100e-03 4.090e-03 4.190e-03 4.380e-03 4.460e-03
  4.080e-03 4.420e-03 3.960e-03 4.230e-03 4.120e-03 4.440e-03 4.420e-03
  4.370e-03 4.380e-03]]

rad = data[0]
azm = data[1]

# From what I understand, I need to create a meshgrid from the zenith and azimuth values
r, th = np.meshgrid(rad, azm)

z = data[2] # This doesn't work as `pcolormesh` expects this to be a 2d array

plt.subplot(projection="polar")

plt.pcolormesh(th, r, z, shading="auto")

plt.plot(azm, r, color="k", ls="none")

plt.show()
  • 注意:我的实际数据为56k行,如下所示(忽略第4列): enter image description here

上面的示例数据是我试图降低这个海量文件的分辨率,所以我只使用了1/500行数据。这可能是降低分辨率的错误方法,如果是,请纠正我

我看到的每个教程都从meshgrid生成的r数组生成z值。这让我对如何将我的z列转换为能够正确映射到天顶和方位角值的二维数组感到困惑。 他们会使用类似这样的东西:

z = (r ** 2.0) / 4.0

因此,采用r的精确形状并应用变换来创建颜色


Tags: 文件theto数据importdatamatplotlibvalue
2条回答

解决方案一直存在于数据文件中。我需要更好地理解np.meshrid实际上做了什么。结果表明,数据已经是一个二维数组,只需要对其进行重塑。我还在文件中发现了一个缺陷,修复后它的行数从56k减少到15k。这足够小,我不需要降低分辨率。 以下是我如何重塑数据以及解决方案的外观:

import matplotlib.pyplot as plt
import numpy as np


with open("data.txt") as f:
    lines = np.array(
        [
            [float(n) for n in line.split("\t")]
            for i, line in enumerate(f.read().splitlines())
        ]
    )

data = [np.reshape(a, (89, 180)) for a in lines.T]

rad = np.radians(data[1])
azm = data[0]
z = data[2]

plt.subplot(projection="polar")
plt.pcolormesh(rad, azm, z, cmap="coolwarm", shading="auto")
plt.colorbar()
plt.show()

enter image description here

绘制给定数据的最简单方法是使用极坐标散点图。 使用蓝色表示低值,红色表示高值,可能看起来像:

import matplotlib.pyplot as plt
import numpy as np

data = [[6.000e+00, 1.200e+01, 1.700e+01, 2.300e+01, 2.800e+01, 3.400e+01, 3.900e+01, 4.500e+01, 5.000e+01, 5.600e+01, 6.200e+01, 6.700e+01, 7.300e+01, 7.800e+01, 8.400e+01, 8.900e+01, 3.934e+01, 4.004e+01, 4.054e+01, 4.114e+01, 4.154e+01, 4.204e+01, 4.254e+01, 4.294e+01, 4.334e+01, 4.374e+01, 4.414e+01, 4.454e+01, 4.494e+01, 4.534e+01, 4.564e+01, 4.604e+01, 4.644e+01, 4.684e+01, 4.714e+01, 4.754e+01, 4.794e+01, 4.824e+01, 4.864e+01, 4.904e+01, 4.944e+01, 4.984e+01, 5.014e+01, 5.054e+01, 5.094e+01, 5.134e+01, 5.174e+01, 5.214e+01, 5.264e+01, 5.304e+01, 5.344e+01, 5.394e+01, 5.444e+01, 5.494e+01, 5.544e+01, 5.604e+01, 5.674e+01, 5.764e+01],
        [1.960e+02, 3.600e+01, 2.360e+02, 7.600e+01, 2.760e+02, 1.160e+02, 3.160e+02, 1.560e+02, 3.560e+02, 1.960e+02, 3.600e+01, 2.360e+02, 7.600e+01, 2.760e+02, 1.160e+02, 3.160e+02, 6.500e+00, 3.400e+00, 3.588e+02, 2.500e+00, 3.594e+02, 3.509e+02, 5.000e-01, 6.900e+00, 1.090e+01, 3.478e+02, 1.250e+01, 1.050e+01, 7.300e+00, 2.700e+00, 3.571e+02, 3.507e+02, 1.060e+01, 3.200e+00, 3.556e+02, 3.480e+02, 7.300e+00, 3.597e+02, 3.527e+02, 1.260e+01, 6.600e+00, 1.200e+00, 3.570e+02, 3.538e+02, 3.520e+02, 3.516e+02, 3.528e+02, 3.560e+02, 1.200e+00, 8.800e+00, 3.567e+02, 1.030e+01, 6.800e+00, 8.300e+00, 3.583e+02, 3.581e+02, 3.568e+02, 3.589e+02],
        [3.580e-04, 6.100e-04, 3.220e-04, 4.850e-04, 4.360e-04, 2.910e-04, 1.120e-03, 2.320e-04, 4.300e-03, 2.680e-04, 1.700e-03, 3.790e-04, 7.460e-04, 8.190e-04, 1.030e-03, 3.650e-03, 3.050e-03, 3.240e-03, 3.340e-03, 3.410e-03, 3.490e-03, 3.290e-03, 3.630e-03, 3.510e-03, 3.320e-03, 3.270e-03, 3.280e-03, 3.470e-03, 3.720e-03, 3.960e-03, 3.980e-03, 3.700e-03, 3.630e-03, 4.100e-03, 4.080e-03, 3.600e-03, 3.990e-03, 4.530e-03, 4.040e-03, 3.630e-03, 4.130e-03, 4.370e-03, 4.340e-03, 4.210e-03, 4.100e-03, 4.090e-03, 4.190e-03, 4.380e-03, 4.460e-03, 4.080e-03, 4.420e-03, 3.960e-03, 4.230e-03, 4.120e-03, 4.440e-03, 4.420e-03, 4.370e-03, 4.380e-03]]

rad = np.radians(data[1])
azm = data[0]
z = data[2]

plt.subplot(projection="polar")
plt.scatter(rad, azm, c=z, cmap='coolwarm')
plt.colorbar()
plt.show()

example plot

用真实数据创建这样一个散点图可以让你了解它的样子。您可能想要选择一个different colormap,这取决于您想要传达的内容。如果点太多,也可以选择较小的点大小(例如plt.scatter(rad, azm, c=z, cmap='plasma', s=1, ec='none')

从非网格数据创建填充图像的一种简单方法是使用256色的tricontourf(给定的数据看起来很单调,所以我没有添加示例图):

plt.subplot(projection="polar")
plt.tricontourf(rad, azm, z, levels=256, cmap='coolwarm')

相关问题 更多 >