You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现半线性半对数次坐标轴?Walter-Leigh气候图绘制求助

Walter-Leigh气候图:降水轴线性+对数刻度问题解决

问题背景

需要绘制Walter-Leigh气候图,核心需求:

  • 降水轴:0-100范围为线性刻度,100以上(截断至300)为对数刻度
  • 温度轴位于左侧,降水轴位于右侧

尝试过Python的ggplot(效果不如R版本)、cloupy内置函数(数据格式限制多、效果差),自定义实现时参考方案修改代码后,出现对数刻度与线性刻度叠加的问题。

原代码及问题效果

原代码(缺失月份变量m):

import pandas as pd
import numpy as np 
import matplotlib.pyplot as pl
from mpl_toolkits.axes_grid1 import make_axes_locatable

# 数据
t=[8.2,8.9,11.2,15.0,19.8,24.5,27.1,26.7,21.6,17.5,13.3,9.7]
p=[77.2,66.2,58.5,63.8,60.4,44.6,24.3,36.7,83.0,73.3,123.0,109.5]

# 自定义绘图代码
fig, axt=pl.subplots()

axt.set_xlabel("Months")
axt.set_ylabel("Temperature")
pl.ylim([0,50])
axt.plot(m,t, "r")

axp=axt.twinx()

axp.plot(m,p)
axp.set_yscale("linear")
axp.set_ylim([0,100])
axp.spines['top'].set_visible(False)
axp.set_ylabel("Precipitation")

divider = make_axes_locatable(axp)

axp2=divider.append_axes("top", size=1, pad=0)
axp2.plot(m,p)
axp2.set_yscale("log")
axp2.set_ylim([100,300])

axp2.spines['bottom'].set_visible(False)
axp2.xaxis.set_ticks_position('top')
axp2.yaxis.set_ticks_position('right')
pl.setp(axp2.get_xticklabels(), visible=False)

pl.show()

当前效果:
当前叠加问题效果

解决方案

问题根源是重复绘制全量降水数据导致线条叠加,且两个轴未在100刻度处对齐。修正后的代码如下:

import pandas as pd
import numpy as np 
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

# 数据定义
t = [8.2,8.9,11.2,15.0,19.8,24.5,27.1,26.7,21.6,17.5,13.3,9.7]
p = [77.2,66.2,58.5,63.8,60.4,44.6,24.3,36.7,83.0,73.3,123.0,109.5]
m = np.arange(1,13)  # 补全月份序列

fig, axt = plt.subplots(figsize=(8,6))

# 左侧温度轴
axt.set_xlabel("月份")
axt.set_ylabel("温度 (°C)", color='#d62728')
axt.set_ylim(0, 50)
axt.plot(m, t, color='#d62728', linewidth=2)
axt.tick_params(axis='y', labelcolor='#d62728')

# 右侧降水线性轴(0-100)
axp = axt.twinx()
axp.set_ylabel("降水量 (mm)", color='#1f77b4')
axp.set_yscale("linear")
axp.set_ylim(0, 100)
# 仅绘制0-100范围内的降水数据
p_linear = np.where(np.array(p) <= 100, np.array(p), np.nan)
axp.plot(m, p_linear, color='#1f77b4', linewidth=2)
axp.tick_params(axis='y', labelcolor='#1f77b4')
axp.spines['top'].set_visible(False)  # 隐藏顶部脊柱,衔接对数轴

# 右侧降水对数轴(100-300)
divider = make_axes_locatable(axp)
axp2 = divider.append_axes("top", size="100%", pad=0)
axp2.set_yscale("log")
axp2.set_ylim(100, 300)
# 仅绘制100以上的降水数据
p_log = np.where(np.array(p) > 100, np.array(p), np.nan)
axp2.plot(m, p_log, color='#1f77b4', linewidth=2)
# 调整轴样式:隐藏底部脊柱,隐藏x轴刻度/标签
axp2.spines['bottom'].set_visible(False)
axp2.tick_params(axis='x', bottom=False, labelbottom=False)
axp2.tick_params(axis='y', labelcolor='#1f77b4')
# 设置对数轴刻度为100、200、300,用普通数值显示而非科学计数
axp2.set_yticks([100, 200, 300])
axp2.get_yaxis().set_major_formatter(plt.ScalarFormatter())
axp2.get_yaxis().set_minor_formatter(plt.ScalarFormatter())

plt.tight_layout()
plt.show()

关键修正点

  1. 补全月份变量:添加m = np.arange(1,13)解决原代码中m未定义的问题
  2. 拆分数据绘制:将降水数据按0-100、100-300拆分,分别在对应轴绘制,避免线条叠加
  3. 轴对齐与样式调整:让线性轴和对数轴在100刻度处无缝衔接,隐藏重叠脊柱,统一降水轴颜色
  4. 对数轴优化:自定义刻度并禁用科学计数,让刻度更直观

内容的提问来源于stack exchange,提问作者Tomislav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:05:05