如何使用Matplotlib并排绘制两张不同的热力工程图表
解决Matplotlib并排绘制两张图表的问题
嘿,你已经搞定了单参数图表的绘制,现在要把Pk=f(Dk)和Pk=f(Subcooling)两张图并排展示对吧?之前用plt.subplots(1,2,1)没成功,核心问题是你没有正确使用subplots返回的**轴对象(Axes)**来分别控制两张图,而是一直用全局的plt.plot,导致所有绘图操作都堆到了同一个画布上。
我帮你修改了代码,下面是完整的解决方案,关键修改点我会在后面说明:
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import math import pyXSteam.XSteam from pyXSteam.XSteam import XSteam sns.set_style("ticks",{'grid.linestyle': '--'}) sns.color_palette("Spectral", as_cmap=True) steamTable = XSteam(XSteam.UNIT_SYSTEM_MKS) # m/kg/sec/°C/bar/W # 输入参数部分保持不变 A = float(input('Define the heat exchange area, sq.m: ')) #3000 m2 d_in = float(input('Define the inner diameter of a single HE tube, mm: ')) #20mm CF = float(input('Define the cleanliness factor of the HE (0.8,0.85,0.9 etc): ')) #0.85 Gw=float(input('Define the CW flow, t/hr: ')) #13000 t/hr z=float(input('Define the number of passes: ')) #1 rho=float(input('Define the density of the liquid, kg/m3: ')) #1000 kg/m3 N=float(input('Define the number of tubes in the HE: ')) #5096 Tcwin_initial=float(input('Define some initial value of Tcwin:')) #20 Dk=float(input('Define the max steam load, t/hr: ')) #274.18 # 原来的函数保持不变,重命名避免和循环变量冲突 def w(): return ((Gw*1000/3600)*z*4*1000000)/(rho*math.pi*((d_in)**2)*N) #2.26 m/s - water velocity inside the tubes def Cp(): return steamTable.CpL_t(Tcwin) def Psat_theor(Tsat_val): return 100*steamTable.psat_t(Tsat_val) def calculate_dk(Dk_val): return Dk_val*1000/(A*3.600) def calculate_K(dk_val, Tcwin_val): return CF * 4070 * ((1.1 * w() / (d_in ** 0.25)) ** (0.12 * CF * (1 + 0.15 * Tcwin_val))) * (1 - (((35 - Tcwin_val) ** 2) * (0.52 - 0.0072 * dk_val) * (CF ** 0.5)) / 1000) # ------------------- 核心修改:创建并排子图 ------------------- # 创建1行2列的子图,figsize设置画布宽度和高度,保证两张图都有足够空间 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6)) labels = [] # 用来收集图例标签 X = np.arange(Dk*0.1,Dk*1.1,Dk*0.1) for Tcwin in np.arange(17,31,2): labels.append(r'$t_{1в}$' + f'={Tcwin} \N{DEGREE SIGN}С') # 计算第一张图的数据:Pk=f(Dk) pk_vs_dk = [] # 计算第二张图的数据:Pk=f(Subcooling) pk_vs_subcooling = [] subcooling_values = [] for Dk_val in X: # 计算当前Dk下的所有参数 dk = calculate_dk(Dk_val) K = calculate_K(dk, Tcwin) Cp_val = Cp() Tcwout_theor = Tcwin + (Dk_val * 2225 / (Cp_val * Gw)) Subcooling = (Tcwout_theor - Tcwin) / ((math.e ** (K * A / (Cp_val * (Gw * 1000 / 3600) * 1000)))-1) Tsat_theor_val = (Tcwout_theor + Subcooling) # 收集对应数据 pk_vs_dk.append(Psat_theor(Tsat_theor_val)) pk_vs_subcooling.append(Psat_theor(Tsat_theor_val)) subcooling_values.append(Subcooling) # ------------------- 分别在两个轴上绘图 ------------------- # 第一张图:Pk=f(Dk) ax1.plot(X, pk_vs_dk) ax1.grid(True, which="both", ls="--", c='gray') ax1.set_xlabel(r'$D_{k}$' + ',т/ч', loc='right') ax1.set_ylabel(r'$P_{k}$' + ',кПа', rotation=0, loc='top') ax1.set_title(r'$P_{k}$' + '=f(' + '$D_{k}$' + ')') # 第二张图:Pk=f(Subcooling) ax2.plot(subcooling_values, pk_vs_subcooling) ax2.grid(True, which="both", ls="--", c='gray') ax2.set_xlabel(r'Subcooling' + ',\N{DEGREE SIGN}С', loc='right') ax2.set_ylabel(r'$P_{k}$' + ',кПа', rotation=0, loc='top') ax2.set_title(r'$P_{k}$' + '=f(' + 'Subcooling' + ')') # ------------------- 设置图例和布局 ------------------- # 给两个子图添加图例(曲线样式一致,保证图例对应关系清晰) ax1.legend(labels) ax2.legend(labels) # 移除多余的边框 sns.despine(ax=ax1) sns.despine(ax=ax2) # 自动调整子图间距,避免标签和标题重叠 plt.tight_layout() plt.show()
关键修改说明:
使用轴对象控制绘图:
用fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))创建了1行2列的子图,后续所有绘图操作都通过ax1和ax2这两个轴对象完成,而不是全局的plt,这样就能分别控制两张图的内容。同时计算两张图的数据:
在循环中,除了计算Pk=f(Dk)的数值,还同步计算了Pk=f(Subcooling)需要的过冷度(Subcooling)和对应Pk值,确保两组数据的对应关系正确。修复变量名冲突:
原代码中函数名(比如dk、K)和循环内的变量名重复,我把函数重命名为calculate_dk、calculate_K,避免了变量覆盖导致的逻辑错误。优化布局和可读性:
使用plt.tight_layout()自动调整子图间距,避免标签和标题重叠;统一收集图例标签,保证两张图的图例对应关系一致。
这样修改后,你就能在程序末尾看到两张并排的图表,分别展示Pk=f(Dk)和Pk=f(Subcooling)的关系啦!
内容的提问来源于stack exchange,提问作者Pavel Tashkinov
相关产品推荐
相关产品推荐

