4D等高线图使用 .nc 文件

huangapple go评论104阅读模式
英文:

4D contour plot using .nc file

问题

I am trying to plot a 4D surface plot from netcdf data which has 4 dimensions: time, lat, long, and lev for 5 variables (DU001, DU002...005). I have to plot the first variable DU001 vs lat, long, and levels (72 levels) such that the x-axis is lat, the y-axis is long, the z-axis is levels, and the DU001 will be represented with color. So far I have tried the below code but I am getting only one surface in my plot.

I think it is only taking one level. How to correct it?

  1. import xarray as xr
  2. import matplotlib.pyplot as plt
  3. from mpl_toolkits.mplot3d import Axes3D
  4. import numpy as np
  5. from matplotlib import cm
  6. path= 'D:\\DATA\\2015\\test_data' # Open the NetCDF file
  7. data = xr.open_dataset('D:\\DATA\\2015\\test_data\\MERRA2_400.inst3_3d_aer_Nv.20150515.SUB.nc')
  8. # Select the DU01 variable and the lat, long, and lev dimensions
  9. lat = data['lat']
  10. lon = data['lon']
  11. lev = data['lev']
  12. DMR = data['DU001']
  13. # Reshape the data
  14. du001_2d = DMR[:, :, :].squeeze()
  15. dmr_values = du001_2d.values.squeeze()
  16. # Create meshgrid for coordinates
  17. lon_2d, lat_2d = np.meshgrid(lon, lat)
  18. # Create the 3D plot
  19. fig = plt.figure()
  20. ax = fig.add_subplot(111, projection='3d')
  21. # Plot the surface for each level
  22. for i, level in enumerate(lev):
  23. ax.plot_surface(lon_2d, lat_2d, dmr_values[i], cmap='viridis')
  24. # Set labels and title
  25. ax.set_xlabel('Longitude')
  26. ax.set_ylabel('Latitude')
  27. ax.set_zlabel('Level')
  28. ax.set_title('3D Plot of Dust Mixing Ratio')
  29. # Set the z-limits based on the valid range of the lev array
  30. ax.set_zlim(lev[0], lev[71]) # Assuming lev is a 1D array
  31. # Display the plot
  32. plt.show()

I don't know where I am going wrong. I am very new to Python. Any help would be appreciated.

英文:

I am trying to plot a 4D surface plot from netcdf data which has 4 dimensions: time, lat, long, and lev for 5 variables (DU001, DU002...005) (sample data). I have to plot the first variable DU001 vs lat, long, and levels (72 levels) such that the x-axis is lat, the y-axis is long, the z-axis is levels, and the DU001 will be represented with color. So far I have tried the below code but I am getting only one surface in my plot 4D等高线图使用 .nc 文件.

I think it is only taking one level. How to correct it?

  1. import xarray as xr
  2. import matplotlib.pyplot as plt
  3. from mpl_toolkits.mplot3d import Axes3D
  4. import numpy as np
  5. from matplotlib import cm
  6. path= 'D:\\DATA\15\\test_data'# Open the NetCDF file
  7. data = xr.open_dataset('D:\\DATA\15\\test_data\\MERRA2_400.inst3_3d_aer_Nv.20150515.SUB.nc')
  8. # Select the DU01 variable and the lat, long, and lev dimensions
  9. lat = data['lat']
  10. lon = data['lon']
  11. lev = data['lev']
  12. DMR = data['DU001']
  13. # Reshape the data
  14. du001_2d = DMR[:, :, :].squeeze()
  15. dmr_values = du001_2d.values.squeeze()
  16. # Create meshgrid for coordinates
  17. lon_2d, lat_2d = np.meshgrid(lon, lat)
  18. # Create the 3D plot
  19. fig = plt.figure()
  20. ax = fig.add_subplot(111, projection='3d')
  21. # Plot the surface for each level
  22. for i, level in enumerate(lev):
  23. ax.plot_surface(lon_2d, lat_2d, dmr_values[i], cmap='viridis')
  24. # Set labels and title
  25. ax.set_xlabel('Longitude')
  26. ax.set_ylabel('Latitude')
  27. ax.set_zlabel('Level')
  28. ax.set_title('3D Plot of Dust Mixing Ratio')
  29. # Set the z-limits based on the valid range of the lev array
  30. ax.set_zlim(lev[0], lev[71]) # Assuming lev is a 1D array
  31. # Display the plot
  32. plt.show()

I don't know where I am going wrong. I am very new to Python. Any help would be appreciated

4D等高线图使用 .nc 文件

sample of what I am trying to plot is 4D等高线图使用 .nc 文件

答案1

得分: 1

你将所有的 dmr_values 绘制在一起,也就是说你看到的只是 dmr_values[-1]。每个层的最大高度约为 6e-8,这就是为什么在使用 0 - 72 的 z 轴范围时它看起来只是一个平的表面。

如果你想要绘制 72 个不同颜色的层,你需要提供 72 个平的表面,并自己着色:

  1. ax.plot_surface(lon_2d,
  2. lat_2d,
  3. np.full_like(lat_2d, level),
  4. facecolors=cm.ScalarMappable(cmap='viridis').to_rgba(dmr_values[i]),
  5. shade=False)

下面是对下方评论的更新:

如果你想要进行插值,你可以使用 3 个填充等值线图来表示三个可见的表面:

  1. import matplotlib as mpl
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. import xarray as xr
  5. path = 'MERRA2_400.inst3_3d_aer_Nv.20150515.SUB.nc'
  6. data = xr.open_dataset(path)
  7. lat = data['lat']
  8. lon = data['lon']
  9. lev = data['lev']
  10. DMR = data['DU001']
  11. fig, ax = plt.subplots(subplot_kw=dict(projection="3d"))
  12. x, y, z = np.meshgrid(lon, lat, lev, indexing='ij')
  13. du = np.swapaxes(DMR[:, :, :].squeeze().values, 0, -1)
  14. kw = {
  15. 'vmin': du.min(),
  16. 'vmax': du.max(),
  17. 'levels': np.linspace(du.min(), du.max(), 20),
  18. }
  19. _ = ax.contourf(
  20. x[:, :, 0], y[:, :, 0], du[:, :, -1],
  21. zdir='z', offset=z.max(), **kw
  22. )
  23. _ = ax.contourf(
  24. x[:, 0, :], du[:, 0, :], z[:, 0, :],
  25. zdir='y', offset=y.min(), **kw
  26. )
  27. c = ax.contourf(
  28. du[-1, :, :], y[0, :, :], z[0, :, :],
  29. zdir='x', offset=x.max(), **kw
  30. )
  31. xmin, xmax = x.min(), x.max()
  32. ymin, ymax = y.min(), y.max()
  33. zmin, zmax = z.min(), z.max()
  34. ax.set(xlim=[xmin, xmax], ylim=[ymin, ymax], zlim=[zmin, zmax],
  35. xlabel='Longitude', ylabel='Latitude', zlabel='Level')
  36. fig.colorbar(c, ax=ax, shrink=0.7)

图片1

图片2

英文:

You plot all dmr_values one on the other, i.e. what you see is just dmr_values[-1]. The maximum height of a layer is about 6e-8, that's why it appears as just one flat surface when using a z-axis range of 0 - 72.

If you want to plot 72 colored layers, you need to provide 72 flat surfaces and color them yourself:

  1. ax.plot_surface(lon_2d,
  2. lat_2d,
  3. np.full_like(lat_2d, level),
  4. facecolors=cm.ScalarMappable(cmap='viridis').to_rgba(dmr_values[i]),
  5. shade=False)

4D等高线图使用 .nc 文件

<hr>

Update for comment below:
If you want to interpolate you could use 3 filled contour plots for the 3 visible surfaces:

  1. import matplotlib as mpl
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. import xarray as xr
  5. path = &#39;MERRA2_400.inst3_3d_aer_Nv.20150515.SUB.nc&#39;
  6. data = xr.open_dataset(path)
  7. lat = data[&#39;lat&#39;]
  8. lon = data[&#39;lon&#39;]
  9. lev = data[&#39;lev&#39;]
  10. DMR = data[&#39;DU001&#39;]
  11. fig, ax = plt.subplots(subplot_kw=dict(projection=&quot;3d&quot;))
  12. x, y, z = np.meshgrid(lon, lat, lev, indexing=&#39;ij&#39;)
  13. du = np.swapaxes(DMR[:, :, :].squeeze().values, 0, -1)
  14. kw = {
  15. &#39;vmin&#39;: du.min(),
  16. &#39;vmax&#39;: du.max(),
  17. &#39;levels&#39;: np.linspace(du.min(), du.max(), 20),
  18. }
  19. _ = ax.contourf(
  20. x[:, :, 0], y[:, :, 0], du[:, :, -1],
  21. zdir=&#39;z&#39;, offset=z.max(), **kw
  22. )
  23. _ = ax.contourf(
  24. x[:, 0, :], du[:, 0, :], z[:, 0, :],
  25. zdir=&#39;y&#39;, offset=y.min(), **kw
  26. )
  27. c = ax.contourf(
  28. du[-1, :, :], y[0, :, :], z[0, :, :],
  29. zdir=&#39;x&#39;, offset=x.max(), **kw
  30. )
  31. xmin, xmax = x.min(), x.max()
  32. ymin, ymax = y.min(), y.max()
  33. zmin, zmax = z.min(), z.max()
  34. ax.set(xlim=[xmin, xmax], ylim=[ymin, ymax], zlim=[zmin, zmax],
  35. xlabel=&#39;Longitude&#39;, ylabel=&#39;Latitude&#39;, zlabel=&#39;Level&#39;)
  36. fig.colorbar(c, ax=ax, shrink=0.7)

4D等高线图使用 .nc 文件

huangapple
  • 本文由 发表于 2023年6月9日 13:40:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76437497.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定