matplotlib 中湖泊的纵向剖面

问题描述 投票:0回答:1

我有一个Python脚本,用于温度可视化。输入数据是这样的:

导入Excel表格

我有这个代码,它工作正常:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# import data from excel file
df = pd.read_excel('temperature_data.xlsx', index_col=0)

# Assign columns to variables
places = df.columns
depth = df.index
temperature = np.ma.masked_invalid(df.to_numpy())

# Creating the graph
fig, ax = plt.subplots()
min_temp = temperature.min()
max_temp = temperature.max()
cs = plt.contourf(places, depth, temperature, cmap='coolwarm', vmin=min_temp, vmax=max_temp)
cs2 = plt.contour(places, depth, temperature, levels=range(round(min_temp), round(max_temp)+1, 1), colors='black')
plt.clabel(cs2, inline=1, fontsize=10, fmt='%d')
plt.title('Teplota vody [°C]')

#plt.xlabel('Places')
plt.ylabel('hloubka [m]')
plt.colorbar(cs, cmap='coolwarm')
plt.gca().invert_yaxis()
plt.show()

但我想要具有平滑轮廓和底线的可视化。像这样的东西:

所需输出

你能帮我一下吗?非常感谢你,杜尚。

我尝试编写一个包含的脚本。

python matplotlib plot
1个回答
0
投票

你可以这样做。首先使用

melt
将数据帧从宽格式转换为长格式以方便操作。删除所有
None
,然后从配置文件名称中提取配置文件编号,并将其转换为
int
以进行绘图。然后使用
meshgrid
创建一个用于插值的网格,并使用
griddata
使用三次插值将温度插值到该网格上。最后,屏蔽插值网格中的所有
nan
值以避免绘图问题。和情节:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy.interpolate import griddata

data = {
    'profile 1': [22.6, 22.6, 22.5, 22.5, 22.4, 22.4, 22.3, 22.3, 21.7, 21.6, 21.6, 21.6, 21.6, 21.4, 21.2, 21.0, 19.5],
    'profile 2': [22.6, 22.6, 22.6, 22.5, 22.4, 22.3, 22.1, 21.8, 21.7, 21.7, 21.6, 21.6, 21.6, 21.1, 20.6, None, None],
    'profile 3': [22.6, 22.6, 22.3, 22.3, 22.2, 22.1, 22.0, 21.8, 21.7, 21.7, 21.6, 21.5, 21.4, 21.1, 20.6, 21.0, None],
    'profile 4': [22.5, 22.4, 21.7, 21.7, 21.0, 18.7, 18.5, 18.3, 18.3, 18.3, None, None, None, None, None, None, None],
    'profile 5': [22.1, 22.1, 21.7, 21.7, 21.0, 16.8, None, None, None, None, None, None, None, None, None, None, None],
    'profile 6': [20.9, 20.9, 19.8, 19.8, 16.8, 16.8, None, None, None, None, None, None, None, None, None, None, None],
    'profile 7': [15.5, 15.2, 15.6, 15.6, 15.7, None, None, None, None, None, None, None, None, None, None, None, None]
}

depth = list(range(17))

df = pd.DataFrame(data, index=depth)

df_long = df.reset_index().melt(id_vars=['index'])
df_long.columns = ['depth', 'profile', 'temperature']

df_long = df_long.dropna()

df_long['profile_num'] = df_long['profile'].str.extract('(\d+)').astype(int) - 1

grid_x, grid_y = np.meshgrid(np.linspace(df_long['profile_num'].min(), df_long['profile_num'].max(), 200), 
                             np.linspace(df_long['depth'].min(), df_long['depth'].max(), 200))
grid_z = griddata((df_long['profile_num'], df_long['depth']), df_long['temperature'], (grid_x, grid_y), method='cubic')

grid_z = np.ma.masked_invalid(grid_z)

fig, ax = plt.subplots()
min_temp = np.nanmin(grid_z)
max_temp = np.nanmax(grid_z)
cs = ax.contourf(grid_x, grid_y, grid_z, cmap='coolwarm', vmin=min_temp, vmax=max_temp)
cs2 = ax.contour(grid_x, grid_y, grid_z, levels=np.arange(int(min_temp), int(max_temp)+1), colors='black')
ax.clabel(cs2, inline=1, fontsize=10, fmt='%d')
ax.set_title('Teplota vody [°C]')
ax.set_xlabel('R. km')
ax.set_ylabel('Hloubka (m n.m.)')
fig.colorbar(cs, ax=ax, cmap='coolwarm')
ax.invert_yaxis()

ax.set_xticks(np.arange(len(df.columns)))
ax.set_xticklabels(df.columns)

plt.show()

这会给你

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.