我有一个Python脚本,用于温度可视化。输入数据是这样的:
我有这个代码,它工作正常:
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()
但我想要具有平滑轮廓和底线的可视化。像这样的东西:
你能帮我一下吗?非常感谢你,杜尚。
我尝试编写一个包含的脚本。
你可以这样做。首先使用
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()
这会给你