解读等值线图的Python绘制方法
作者:Jeremy_lf
这篇文章主要介绍了解读等值线图的Python绘制方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
等值线图的Python绘制方法
等值线图或等高线图在科学界经常用到,它是由一些封闭的曲线组成的,来表示三维结构表面。
虽然看起来复杂,其实用matplotlib实现起来并不难。
代码如下:
import numpy as np import matplotlib.pyplot as plt dx=0.01;dy=0.01 x=np.arange(-2.0,2.0,dx) y=np.arange(-2.0,2.0,dy) X,Y=np.meshgrid(x,y) def f(x,y): return(1-y**5+x**5)*np.exp(-x**2-y**2) C=plt.contour(X,Y,f(X,Y),8,colors='black') #生成等值线图 plt.contourf(X,Y,f(X,Y),8) plt.clable(C,inline=1,fontsize=10)
结果如下:
使用等值线图,在图的一侧增加图例作为图表中所用颜色的说明几乎是必需的,在上述代码最后增加colorbar()函数就可以实现。
plt.colorbar()
python等值线图绘制,计算合适的等值线间距
python按照给定坐标点进行插值并绘制等值线图
import matplotlib.pyplot as plt import numpy as np import math import pandas as pd import io import copy def get_gap(gap): gap = str(gap) gap_len = len(gap) gap_list = list(map(int, gap)) top_value = int(gap_list[0]) gap_bottom = top_value * (10 ** (gap_len - 1)) gap_mid = gap_bottom + int((10 ** (gap_len - 1) / 2)) gap_top = (top_value + 1) * (10 ** (gap_len - 1)) gap_value = [gap_bottom, gap_mid, gap_top] gap_bottom_dis = abs(int(gap) - gap_bottom) gap_mid_dis = abs(int(gap) - gap_mid) gap_top_dis = abs(int(gap) - gap_top) range_list = [gap_bottom_dis, gap_mid_dis, gap_top_dis] min_i = 0 for i in range(len(range_list)): if range_list[i] < range_list[min_i]: min_i = i final_gap = gap_value[min_i] return int(final_gap) def interpolation(lon, lat, lst): # 网格插值——反距离权重法 p0 = [lon, lat] sum0 = 0 sum1 = 0 temp = [] for point in lst: if lon == point[0] and lat == point[1]: return point[2] Di = distance(p0, point) ptn = copy.deepcopy(point) ptn = list(ptn) ptn.append(Di) temp.append(ptn) temp1 = sorted(temp, key=lambda point: point[3]) for point in temp1[0:15]: sum0 += point[2] / math.pow(point[3], 2) sum1 += 1 / math.pow(point[3], 2) return sum0 / sum1 def distance(p, pi): dis = (p[0] - pi[0]) * (p[0] - pi[0]) + (p[1] - pi[1]) * (p[1] - pi[1]) m_result = math.sqrt(dis) return m_result def gap_equal_line_value(min_value, max_value , n_group): # 计算较为合适的gap来获取最终的分界值 n_group = int(n_group) gap = abs((max_value - min_value) / n_group) if gap >= 1: gap = int(math.ceil(gap)) final_gap = get_gap(gap) else: gap_effect = np.float('%.{}g'.format(1) % Decimal(gap)) gap_effect = gap * (10 ** (len(str(gap_effect)) - 2)) gap_multi = gap_effect / gap gap = math.ceil(gap_effect) final_gap = get_gap(gap) final_gap = final_gap / gap_multi #final_gap = np.float('%.{}g'.format(4) % Decimal(final_gap)) bottom = min_value + final_gap if final_gap < 1: final_bottom = bottom else: if abs(bottom) >= 1: bottom_effect = math.ceil(abs(bottom)) final_bottom = get_gap(bottom_effect) else: bottom_effect = np.float('%.{}g'.format(1) % (abs(bottom))) bottom_multi = bottom_effect / (abs(bottom)) bottom_effect = math.ceil(bottom_effect) final_bottom = get_gap(bottom_effect) final_bottom = (final_bottom / bottom_multi) if bottom < 0: final_bottom = final_bottom * (-1) else: pass # print(final_bottom) #final_bottom = keep_decimal(final_bottom) equal_line_value = [] if math.floor(min_value) >= final_bottom: equal_line_value.append(final_bottom-1) else: equal_line_value.append(math.floor(min_value)) equal_line_value.append(final_bottom) for i in range(1, n_group-1): final_bottom = final_bottom + final_gap equal_line_value.append(final_bottom) final_bottom = final_bottom + final_gap if final_bottom <= max_value: equal_line_value.append(math.ceil(max_value)) else: equal_line_value.append(final_bottom) print(equal_line_value) return equal_line_value def equal_line_value(min_value, max_value, n_group): # 直接按照分组字数计算分界值 n_group = int(n_group) gap = abs((max_value - min_value) / n_group) equal_line_value = [] if gap <= 0: gap_flag = False #gap为0 equal_line_value.append(max_value-1) equal_line_value.append(max_value+1) else: gap_flag = True equal_line_value.append(min_value) now_value = min_value for i in range(1, n_group): now_value = now_value + gap equal_line_value.append(now_value) equal_line_value.append(max_value) res = { 'gap_flag': gap_flag, 'equal_line_value': equal_line_value } return res def contour_line_plot(grid_x_plot, grid_y_plot, f_plot, levels,x_long,y_long,n_group): n_group = int(n_group) color1 = '#74E3AD' color2 = '#17BD6D' color3 = '#05A156' color4 = '#038A49' color5 = '#165C3A' color6 = '#BDBDBD' color7= '#848484' color8 = '#FA58F4' color9 = '#FF00BF' color10 = '#FF0080' color11 = '#8A084B' color12 = '#3B0B24' Colors_all = (color1, color2, color3, color4, color5, color6, color7, color8, color9, color10, color11, color12) Colors = Colors_all[0:n_group] fig = plt.figure(figsize=(x_long,y_long)) ax = plt.subplot() ax.contourf(grid_x_plot, grid_y_plot, f_plot, levels=levels, colors = Colors) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) ax.set_xticks([]) ax.set_yticks([]) plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0) plt.margins(0, 0) # 输出为二进制流 canvas = fig.canvas buffer = io.BytesIO() # 获取输入输出流对象 canvas.print_png(buffer) # 将画布上的内容打印到输入输出流对象 data = buffer.getvalue() # 获取流的值 buffer.close() plt.close() # with open('hhh.png', mode='wb') as f: # f.write(data) return data def contour_line(data,n_group): ''' data:数组,[[x1,y1,value1],[x2,y2,value2],[x2,y2,value2],......] 例:data = [[5,5,11],[5,25,21],[10,25,45],[10,5,5],[8,5,60]] n_group:分组组数 ''' data = pd.DataFrame(data,columns=['x', 'y', 'f']) min_x = data['x'].min() max_x = data['x'].max() min_y = data['y'].min() max_y = data['y'].max() # 设置等值线图大小 x_long = 40.0 y_long = 40.0 lst = data.iloc[:, 0:3].values # 设置网格大小 n_grid = 50 grid_x = np.linspace(min_x, max_x, n_grid) grid_y = np.linspace(min_y, max_y, n_grid) # 得到所有网格坐标点 data_xy_list = [] for i in range(len(grid_x)): for j in range(len(grid_y)): data_xy_list.append([grid_x[i], grid_y[j]]) data_xy = pd.DataFrame(data_xy_list, columns=['x', 'y']) # 得到所有网格坐标点和对应的值 insert_value_list = [] for i in range(len(data_xy)): value = interpolation(data_xy.iloc[i, 0], data_xy.iloc[i, 1], lst) insert_value_list.append([data_xy.iloc[i, 0], data_xy.iloc[i, 1], value]) insert_data = pd.DataFrame(insert_value_list, columns=['x', 'y', 'f']) # 得到等值线的分界值 equal_value_res = equal_line_value(insert_data.loc[:, ['f']].min()[0], insert_data.loc[:, ['f']].max()[0],n_group) equal_value_list = equal_value_res['equal_line_value'] f_plot = insert_data.loc[:, ['f']].values.reshape(n_grid, n_grid) grid_y_plot, grid_x_plot = np.meshgrid(grid_y, grid_x) plt_msg = contour_line_plot(grid_x_plot, grid_y_plot, f_plot, equal_value_list,x_long,y_long,n_group) #data = data.set_index(axis.index) if equal_value_res['gap_flag'] == False: equal_value_list = [insert_data.loc[:, ['f']].min()[0]-1, insert_data.loc[:, ['f']].min()[0]] res = { # 等值线图 'plt_msg': plt_msg, # 等值线图数据流 'equal_value_list': equal_value_list, # 间距,标签 'xy_msg': [(min_x, max_x), (min_y, max_y)], # 边界坐标 'plot_data': data, # 绘图点数据 'plot_size': [x_long, y_long] } return res if __name__ == "__main__": res = contour_line([[5, 5, 11], [5, 25, 21], [10, 25, 45], [10, 5, 5], [8, 5, 60]], 5)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。