Matplotlib多Y轴绘图修改:降雨转条形图置于顶部,共享大肠杆菌Y轴
Matplotlib时间序列图定制修改方案
你需要的三处调整均已在代码中实现,最终为降雨条形在上、大肠杆菌散点在下的双Y轴结构,完整可运行代码如下:
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt import pandas as pd # 测试用数据集,实际使用时替换为csv读取逻辑即可 data = {'Date_1': ['1/17/2018', '2/21/2018', '3/21/2018', '4/18/2018', '5/17/2018', '6/20/2018', '7/18/2018', '8/8/2018', '9/19/2018', '10/24/2018', '11/21/2018', '12/19/2018', '1/16/2019', '2/20/2019', '3/20/2019', '4/29/2019', '5/30/2019', '6/19/2019', '7/19/2019', '8/21/2019', '9/18/2019', '10/16/2019', '1/22/2020', '2/19/2020'], 'FLOW_OUTcms': [0.00273, 0.01566, 0.02071, 0.00511, 0.00777, 0.00581, 0.00599, 0.00309, 0.00204, 0.04024, 0.00456, 0.0376, 0.00359, 0.00301, 0.01515, 0.02796, 0.00443, 0.03602, 0.0071, 0.00255, 0.00159, 0.00319, 0.04443, 0.04542], 'Rain': [0.0, 30.4, 2.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.7, 0.0, 0.0, 0.1, 0.1, 0.0, 0.0, 0.1, 0.0, 1.1, 0.1, 33.3, 0.0], 'Mod_Ec': [10840, 212, 1953, 2616, 2715, 2869, 3050, 2741, 5479, 1049, 2066, 146, 6618, 7444, 992, 2374, 6602, 82, 5267, 3560, 4845, 1479, 58, 760], 'Obs_Ec': [2500, 69000, 13000, 3300, 1600, 2400, 2300, 1400, 1600, 1300, 10000, 20000, 2000, 2500, 2900, 1500, 280, 260, 64, 59, 450, 410, 3900, 870]} df = pd.DataFrame(data) # 实际使用时替换为下面的csv读取代码 # source = "Sample_table.csv" # df = pd.read_csv(source, encoding = 'unicode_escape') x = df['Date_1'] y1 = df['Obs_Ec'] y2 = df['Rain'] y3 = df['Mod_Ec'] # 初始化左侧Y轴(大肠杆菌浓度) fig, ax1 = plt.subplots(1,1,figsize=(10,6), dpi= 80) # 初始化右侧Y轴(降雨量) ax2 = ax1.twinx() # 绘制降雨量条形图,反向Y轴 ax2.bar(x, y2, color='tab:blue', alpha=0.6, zorder=0) ax2.set_ylim(0,35) ax2.invert_yaxis() # 实现0值在顶部,数值向下递增 # 左侧Y轴绘制观测、模拟大肠杆菌散点,共享刻度 ax1.set_ylim(0,80000) # 观测大肠杆菌散点 ax1.scatter(x, y1, color="red", s=50, alpha=0.5, linewidths=0.5, label='Observed E. coli') # 模拟大肠杆菌散点,直接用ax1绘制,共享左侧刻度 ax1.scatter(x, y3, color="green", s=50, alpha=0.5, linewidths=0.5, label='Modelled E. coli') # 装饰配置 # ax1 配置 ax1.set_xlabel('Date', fontsize=20) ax1.set_ylabel('E. coli - cfu ml-1', color='tab:red', fontsize=20) ax1.tick_params(axis='y',rotation=0, labelcolor='tab:red') ax1.grid(alpha=.0) ax1.tick_params(axis='both', labelsize=14) ax1.legend(loc='right',fontsize=14, bbox_to_anchor=(0.35, -0.20)) # ax2 配置 ax2.set_ylabel("Rainfall - mm", color='tab:blue', fontsize=20) ax2.tick_params(axis='y', labelcolor='tab:blue') ax2.tick_params(axis='both', labelsize=15) ax2.set_xticks(np.arange(0, len(x), 4)) ax2.set_xticklabels(x[0::4], rotation=15, fontdict={'fontsize':10}) ax2.set_title("SP051 - without SR (validation 2018-2020)", fontsize=22) ax2.legend(['rainfall'], loc='right',fontsize=14, bbox_to_anchor=(1.05, -0.20)) fig.tight_layout() plt.show()
核心修改点说明
- 移除了冗余的第三个坐标轴
ax3,直接在左侧Y轴ax1上绘制模拟大肠杆菌散点,天然共享左侧刻度与范围,不需要额外配置也不会产生多余刻度 - 将降雨量的折线绘制方法
plot替换为bar实现条形图,添加zorder参数控制图层顺序,避免条形遮挡下方散点 - 调用
ax2.invert_yaxis()方法实现降雨量Y轴反向,满足0值在顶部、数值向下递增的需求,条形自然从顶部向下延伸展示降雨量大小 - 简化了图例配置逻辑,将两个大肠杆菌散点的图例合并到左侧坐标轴统一管理
内容的提问来源于stack exchange,提问作者Phylthy Phil
相关产品推荐
相关产品推荐

