如何绘制数值跨度悬殊的DataFrame双列对比单列图表?
解决方法
下面几种方案可以帮你在同一图表(或同画布)中清晰展示B、C随A的变化规律:
1. 双Y轴绘图
用两个独立的Y轴分别对应B和C的数值范围,既能在同一图中对比趋势,又不会因为跨度大掩盖小数值细节。
import pandas as pd import matplotlib.pyplot as plt data = {'A': [ -0.9, -0.5, -0.3, -0.1, 0, 0.2, 0.4, 0.5, 0.8, 0.9,], 'B': [0, 0, 17, 59, 243, 6777, 35531, 909876, 3, 8], 'C': [7312, 22434, 10787, 4576, 25, 0, 5, 12, 0, 32]} df = pd.DataFrame(data) fig, ax1 = plt.subplots() # 绘制B列,用左Y轴 color = 'tab:blue' ax1.set_xlabel('A') ax1.set_ylabel('B', color=color) ax1.plot(df['A'], df['B'], color=color, marker='o') ax1.tick_params(axis='y', labelcolor=color) # 创建右Y轴,绘制C列 ax2 = ax1.twinx() color = 'tab:orange' ax2.set_ylabel('C', color=color) ax2.plot(df['A'], df['C'], color=color, marker='s') ax2.tick_params(axis='y', labelcolor=color) fig.tight_layout() plt.show()
这个方案能直观对比两列随A的变化趋势,比如你提到的A<0时C值高、A>0时B值高的模式会非常明显。
2. 带偏移的对数变换(同一Y轴)
如果希望用同一Y轴展示,可对数据做log1p变换(即log(1 + x)),它能把0映射为0,同时大幅压缩大数值的跨度,保留小数值的差异:
import pandas as pd import matplotlib.pyplot as plt import numpy as np data = {'A': [ -0.9, -0.5, -0.3, -0.1, 0, 0.2, 0.4, 0.5, 0.8, 0.9,], 'B': [0, 0, 17, 59, 243, 6777, 35531, 909876, 3, 8], 'C': [7312, 22434, 10787, 4576, 25, 0, 5, 12, 0, 32]} df = pd.DataFrame(data) # 对B、C做log1p变换 df['B_log'] = np.log1p(df['B']) df['C_log'] = np.log1p(df['C']) # 同一图绘制变换后的数据 df.plot(x='A', y=['B_log', 'C_log'], kind='line', marker=['o', 's']) plt.ylabel('log(1 + value)') plt.legend(['B (log1p)', 'C (log1p)']) plt.show()
注意:变换后Y轴是对数刻度的衍生值,需要结合原始数据解读,但能清晰看到两列的相对趋势变化。
3. 共享X轴的子图
把B和C的趋势图放在同一画布的上下子图,共享X轴(A列),这样各自的Y轴独立,细节都能看清:
import pandas as pd import matplotlib.pyplot as plt data = {'A': [ -0.9, -0.5, -0.3, -0.1, 0, 0.2, 0.4, 0.5, 0.8, 0.9,], 'B': [0, 0, 17, 59, 243, 6777, 35531, 909876, 3, 8], 'C': [7312, 22434, 10787, 4576, 25, 0, 5, 12, 0, 32]} df = pd.DataFrame(data) # 创建2行1列的子图,共享X轴 fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(8, 6)) # 绘制B列 ax1.plot(df['A'], df['B'], color='tab:blue', marker='o') ax1.set_ylabel('B') ax1.grid(True) # 绘制C列 ax2.plot(df['A'], df['C'], color='tab:orange', marker='s') ax2.set_xlabel('A') ax2.set_ylabel('C') ax2.grid(True) plt.tight_layout() plt.show()
这个方案适合需要同时观察两列各自数值细节的场景,上下对齐的子图也方便对比同一A值下的B、C变化。
内容的提问来源于stack exchange,提问作者Prathibha K
相关产品推荐
相关产品推荐

