网络编程
位置:首页>> 网络编程>> Python编程>> 解读等值线图的Python绘制方法

解读等值线图的Python绘制方法

作者:Jeremy_lf  发布时间:2021-11-21 19:54:08 

标签:等值线图,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)

结果如下:

解读等值线图的Python绘制方法

使用等值线图,在图的一侧增加图例作为图表中所用颜色的说明几乎是必需的,在上述代码最后增加colorbar()函数就可以实现。

plt.colorbar()

解读等值线图的Python绘制方法

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)

来源:https://blog.csdn.net/Jeremy_lf/article/details/83445402

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com