Figure_raster_mapping.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. """
  2. Author: Wanxue Zhu
  3. Time: 2025 - April - 18
  4. Description: 这个代码用于绘制栅格地图,第一个函数是绘制地图的,第二个是绘制栅格数据的直方图
  5. """
  6. import geopandas as gpd
  7. import rasterio
  8. from rasterio.mask import mask
  9. import matplotlib.pyplot as plt
  10. import numpy as np
  11. import json
  12. from matplotlib.colors import ListedColormap, BoundaryNorm
  13. from rasterio.plot import show
  14. import os
  15. os.chdir(r"D:\土壤-大创\Irrigation_Water\Raster")
  16. # 设置全局字体为 Arial,并设置中文字体(SimHei或Microsoft YaHei)
  17. plt.rcParams['font.family'] = 'Arial'
  18. plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
  19. plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei'] # 添加多个中文字体
  20. """
  21. mapping raster绘图函数的各参数含义
  22. - shp_path: 输入的矢量数据的路径
  23. - tif_path: 输入的栅格数据的路径
  24. - color_map_name: 使用的色彩方案,详细每个颜色方案请见后文
  25. - title_name: 输出数据的图的名称
  26. - output_path: 输出保存的图片的路径
  27. - output_size
  28. 其它说明:
  29. - 目前只划分了6个颜色等级
  30. - 默认的
  31. """
  32. def mapping_raster(shp_path, tif_path, color_map_name, title_name, output_path, output_size):
  33. gdf = gpd.read_file(shp_path) #--------------------------------------------读取矢量边界
  34. with rasterio.open(tif_path) as src: #-------------------------------------读取并裁剪栅格数据
  35. geoms = [json.loads(gdf.to_json())["features"][0]["geometry"]]
  36. out_image, out_transform = mask(src, geoms, crop=True)
  37. out_meta = src.meta.copy()
  38. raster = out_image[0].astype('float16') #----------------------------------------------------提取数据并处理无效值
  39. nodata = out_meta.get("nodata", None)
  40. if nodata is not None:
  41. raster[raster == nodata] = np.nan
  42. bounds = np.nanpercentile(raster, [0, 20, 40, 60, 80, 90, 100])#----------根据分位数分为6个等级
  43. norm = BoundaryNorm(bounds, ncolors=len(bounds) - 1)
  44. cmap = ListedColormap(color_map_name)#------------------------------------自定义颜色设定
  45. fig, ax = plt.subplots(figsize=(output_size, output_size))#---------------绘图
  46. show(raster, transform=out_transform, ax=ax, cmap=cmap, norm=norm)
  47. gdf.boundary.plot(ax=ax, color='black', linewidth=1)#---------------------添加矢量边界
  48. ax.set_title(title_name, fontsize=20)
  49. ax.set_xlabel("Longitude", fontsize=18)
  50. ax.set_ylabel("Latitude", fontsize=18)
  51. ax.grid(True, linestyle='--', color='gray', alpha=0.5)#-------------------经纬网与图形设置
  52. ax.tick_params(axis='y', labelrotation=90)#-------------------------------让经纬网的纬度标签竖着显示
  53. tick_labels = [f"{bounds[i]:.1f}" for i in range(len(bounds) - 1)]#-------图例标签(保留一位小数)
  54. cbar = plt.colorbar(
  55. plt.cm.ScalarMappable(norm=norm, cmap=cmap),
  56. ax=ax,
  57. ticks=[(bounds[i] + bounds[i+1]) / 2 for i in range(len(bounds) - 1)],
  58. shrink=0.6, # 缩小色带高度
  59. aspect=15 # 细长效果
  60. )
  61. cbar.ax.set_yticklabels(tick_labels)
  62. cbar.set_label("Values")
  63. plt.tight_layout()
  64. plt.savefig(f"{output_path}"+'.jpg', dpi=300)
  65. plt.show()
  66. #设定一些常用的colormap
  67. colormap1 = ['#FFFECE', '#FFF085', '#FEBA17','#BE3D2A','#74512D', '#4E1F00'] #黄-橙-棕
  68. colormap2 = ['#F6F8D5', '#98D2C0', '#4F959D', '#205781', '#143D60','#2A3335'] #蓝色系
  69. colormap3 = ['#FFEFC8', '#F8ED8C', '#D3E671', '#89AC46', '#5F8B4C', '#355F2E']#淡黄-草绿
  70. colormap4 = ['#F0F1C5', '#BBD8A3', '#6F826A', '#BF9264', '#735557', '#604652']#绿色-棕色
  71. colormap5 = ['#FCFAEE', '#FBF3B9', '#FFDCCC', '#FDB7EA', '#B7B1F2', '#8D77AB']#黄-粉-紫
  72. colormap6 = ['#15B392', '#73EC8B', '#FFEB55', '#EE66A6', '#D91656', '#640D5F']#绿-黄-红-紫
  73. # 调用示例:
  74. shp_path = "Lechang.shp"
  75. tif_path = r"D:\土壤-大创\Irrigation_Water\Raster\旱地.tif"
  76. color_map_name = colormap6 # 颜色盘名称
  77. title_name = r"Prediction Cd"
  78. output_path = r'..\Figures\Prediction_results-旱地'
  79. output_size = 12
  80. mapping_raster(shp_path, tif_path, color_map_name, title_name, output_path, output_size)
  81. import rasterio
  82. import numpy as np
  83. import matplotlib.pyplot as plt
  84. import seaborn as sns
  85. from matplotlib import font_manager
  86. #-------------------2. 画直方图--------------
  87. # 读取 GeoTIFF 文件
  88. def plot_tif_histogram(file_path,figsize=(10, 6),xlabel='像元值',ylabel='频率密度',
  89. title='GeoTIFF 波段值分布图',save_path=None ):
  90. """
  91. file_path (str): GeoTIFF 文件路径
  92. figsize (tuple): 图像尺寸,如 (10, 6)
  93. xlabel (str): 横坐标标签
  94. ylabel (str): 纵坐标标签
  95. title (str): 图标题
  96. save_path (str): 可选,保存图片路径(含文件名和扩展名)
  97. """
  98. sns.set(style='ticks')
  99. with rasterio.open(file_path) as src:
  100. band = src.read(1)
  101. nodata = src.nodata
  102. if nodata is not None:
  103. band = np.where(band == nodata, np.nan, band)
  104. band_flat = band.flatten()
  105. band_flat = band_flat[~np.isnan(band_flat)]
  106. plt.figure(figsize=figsize)
  107. sns.histplot(band_flat, bins=100, color='steelblue', alpha=0.7, edgecolor='black',stat='density')
  108. sns.kdeplot(band_flat, color='red', linewidth=2)
  109. plt.xlabel(xlabel, fontsize=14)
  110. plt.ylabel(ylabel, fontsize=14)
  111. plt.title(title, fontsize=16)
  112. plt.grid(True, linestyle='--', alpha=0.5)
  113. plt.tight_layout()
  114. if save_path:
  115. plt.savefig(save_path, dpi=300, format='jpg', bbox_inches='tight')
  116. print(f"Save figures to:{os.path.abspath(save_path)}")
  117. plt.show()
  118. file_path = r'D:\土壤-大创\Irrigation_Water\Raster\旱地.tif'
  119. save_file_path = r'..\Figures\Prediction_frequency-旱地.jpg'
  120. plot_tif_histogram(file_path,figsize=(6, 6),xlabel='Cd content',ylabel='Frequency',
  121. title='County level Cd Frequency',save_path=save_file_path )