用java语言JFreeChart库来绘制水文图形

通常情况很多水文数据需要绘制成图形展示更形象,今天我们通过新安江水文模型数据来绘图,开始之前我们先简单介绍一下:新安江水文模型实现原理是什么?可以解决哪些问题?需要输入哪些数据,同时能够输出哪些数据?

1、新安江水文模型实现原理

新安江模型是一个常用的降雨径流模型,主要用于模拟中小流域的水文过程。该模型基于水文循环的基本原理,核心是模拟降雨后水在流域内的转化与分配。模型分为三个层次:上层、下层和地下,分别用于模拟不同土壤层的水分运动。

模型的基本原理:

降雨入渗机制:模型将流域分为蒸发区、产流区和壤中流区,根据降雨量以及土壤水分饱和度决定降雨的去向(径流或渗流)。

径流分配:模型根据流域特性和降雨量将降雨转化为表面径流、壤中流和地下径流,最终汇集到河道中。

蒸发蒸腾损失:模型中包含蒸发与蒸腾损失过程,这一部分影响了有效降雨量的大小。

河道汇流:经过降雨入渗和径流分配,最终通过河道汇流计算出流域出口的流量过程线。

2、新安江模型的适用场景

该模型适用于:

  • 模拟中小流域的洪水过程。

  • 水资源规划、洪水预报等。

  • 评估流域水文过程中的洪峰流量、洪水量等水文要素。

3、输入数据

要运行新安江模型,通常需要以下数据:

降雨量:流域的逐时或逐日降雨数据。

蒸发量:逐时或逐日蒸发量数据。

流域面积:流域的基本地理信息。

土壤含水量:初始土壤的含水状况。

地形和土壤类型参数:用于描述流域地形、坡度和土壤的参数。

4、输出数据

新安江模型输出的数据主要包括:

流域出口处的径流量:通常是逐时或逐日的流量过程线。

洪峰流量:模拟洪水时段的最大流量。

径流系数:用于分析降雨转化为径流的效率。

5、用Java语言编写新安江模型

Java语言可以通过面向对象的方式实现新安江水文模型,主要包含以下模块:

降雨径流转化模块:基于降雨数据和流域参数,计算径流。

蒸发蒸腾模块:根据输入的蒸发数据,计算蒸发损失。

河道汇流模块:根据径流数据,计算河道的汇流过程。

输出模块:将流量过程线、洪峰流量等结果输出并保存。

参考水文模型文章:

6、使用JFreeChart绘制图形

pom文件引入jar包

     <dependency>
            <groupId>org.jfree</groupId>
            <artifactId>jfreechart</artifactId>
            <version>1.5.3</version> <!-- 确保选择最新的稳定版本 -->
        </dependency>

        <!-- JFreeChart UI library (for ApplicationFrame and other UI components) -->
        <dependency>
            <groupId>org.jfree</groupId>
            <artifactId>jfreechart-ui</artifactId>
            <version>1.0.1</version> <!-- 确保选择与jfreechart兼容的版本 -->
        </dependency>

        <!-- Optional: JCommon library (JFreeChart 的支持库) -->
        <dependency>
            <groupId>org.jfree</groupId>
            <artifactId>jcommon</artifactId>
            <version>1.0.24</version> <!-- 确保匹配的版本 -->
        </dependency>

你可以用JFreeChart库来绘制流量过程线图和降雨量柱状图,示例代码如下:

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.data.category.DefaultCategoryDataset;

public class XinAnJiangModelTu extends ApplicationFrame {

    public XinAnJiangModelTu(String title) {
        super(title);
        JFreeChart lineChart = ChartFactory.createLineChart(
                "流域出口流量过程线",
                "时间", "流量 (m³/s)",
                createDataset(),
                PlotOrientation.VERTICAL,
                true, true, false);

        ChartPanel chartPanel = new ChartPanel(lineChart);
        chartPanel.setPreferredSize(new java.awt.Dimension(800, 600));
        setContentPane(chartPanel);
    }

    private DefaultCategoryDataset createDataset() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        // 模拟的数据,实际数据应由新安江模型的计算结果提供
        dataset.addValue(200, "流量", "1小时");
        dataset.addValue(300, "流量", "2小时");
        dataset.addValue(400, "流量", "3小时");
        dataset.addValue(350, "流量", "4小时");
        dataset.addValue(320, "流量", "5小时");
        return dataset;
    }

    public static void main(String[] args) {
        XinAnJiangModelTu chart = new XinAnJiangModelTu("新安江水文模型输出图");
        chart.pack();
        chart.setVisible(true);
    }
}

7、集成到水文模型代码


import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.data.category.DefaultCategoryDataset;

public class XinAnJiangModelTotal extends ApplicationFrame {
    // 模型参数和数据同上...
    // 模型参数
    private double Sm = 80;   // 饱和产流容量 (mm)
    private double ex = 1.5;  // 产流指数
    private double Kg = 0.4;  // 地下径流消退系数
    private double Ki = 0.3;  // 壤中流消退系数
    private double Cs = 0.15; // 壤中流系数
    private double Cg = 0.85; // 地下径流系数
    private double Imp = 0.05; // 不透水面积比例
    private double Wm = 120;  // 最大蓄水容量 (mm)

    // 初始化降雨和蒸发数据
    private double[] rainfall = {10, 5, 15, 20, 0, 5, 0, 10};  // 每日降雨量
    private double[] evaporation = {2, 3, 4, 2, 1, 3, 2, 3};  // 每日蒸发量
    private int n = rainfall.length;  // 时间步长

    // 存储各项结果的数组
    private double[] Qs = new double[n];  // 壤中流
    private double[] Qg = new double[n];  // 地下径流
    private double[] R = new double[n];   // 总径流

    // 初始流域水储存量
    private double W = 50;  // 初始水储存量 (mm)

    public void runModel() {
        for (int t = 0; t < n; t++) {
            // 更新流域蓄水量
            W += rainfall[t] - evaporation[t];

            // 防止水储存超过最大容量或小于0
            if (W > Wm) {
                W = Wm;
            } else if (W < 0) {
                W = 0;
            }

            // 计算地表径流
            double Rs = 0;
            if (W > Sm) {
                Rs = Cs * (W - Sm); // 计算地表径流
            }

            // 壤中流和地下径流计算
            double Ri = Ki * W;  // 壤中流
            double Rg = Kg * W;  // 地下径流

            // 总径流计算
            R[t] = Rs + Ri + Rg;

            // 记录壤中流和地下径流
            Qs[t] = Ri;
            Qg[t] = Rg;

            // 更新蓄水量
            W -= (Rs + Ri + Rg);
        }
    }


    public XinAnJiangModelTotal(String title) {
        super(title);
    }

    public void displayResults() {
        //日\降雨\蒸发\总径流\土壤流量\地面流量
        System.out.println("Day\tRainfall\tEvaporation\tTotal Runoff\tSoil Flow\tGround Flow");
        System.out.println("日\t  降雨\t     蒸发\t     总径流\t    土壤流量\t   地面流量");
        for (int t = 0; t < n; t++) {
            System.out.printf("%d\t%.2f\t\t%.2f\t\t%.2f\t\t%.2f\t\t%.2f\n",
                    t + 1, rainfall[t], evaporation[t], R[t], Qs[t], Qg[t]);
        }
    }

    // 新增方法:创建数据集
    private DefaultCategoryDataset createDataset() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        // 将每种结果添加到数据集中
        for (int t = 0; t < n; t++) {
            dataset.addValue(rainfall[t], "Rainfall", Integer.toString(t + 1));
            dataset.addValue(evaporation[t], "Evaporation", Integer.toString(t + 1));
            dataset.addValue(R[t], "Total Runoff", Integer.toString(t + 1));
            dataset.addValue(Qs[t], "Soil Flow", Integer.toString(t + 1));
            dataset.addValue(Qg[t], "Ground Flow", Integer.toString(t + 1));
        }

        return dataset;
    }

    // 新增方法:创建图表
    private JFreeChart createChart(DefaultCategoryDataset dataset) {
        return ChartFactory.createLineChart(
                "XinAnJiang Model Results",  // 图表标题
                "Day",                      // X轴标签
                "Value (mm)",               // Y轴标签
                dataset,                    // 数据集
                PlotOrientation.VERTICAL,   // 图表方向
                true,                       // 是否显示图例
                true,                       // 是否使用工具提示
                false                       // 是否生成URLs
        );
    }

    // 新增方法:显示图表
    public void showChart() {
        DefaultCategoryDataset dataset = createDataset();
        JFreeChart chart = createChart(dataset);

        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(800, 600));
        setContentPane(chartPanel);

        // 创建和显示窗口
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
        XinAnJiangModelTotal model = new XinAnJiangModelTotal("XinAnJiang Hydrological Model");
        model.runModel();  // 运行模型
        model.displayResults();  // 输出结果

        // 显示图表
        model.showChart();
    }
}

8、输出结果

结构化数据;

图形结果如下:

绘图可参考:https://www.genban.org/teach/teach-63362.html

9、整体实现步骤:

  1. 建立模型类:创建包含输入参数(如降雨量、蒸发量等)和输出结果的类结构。

  2. 实现算法:根据新安江模型的原理,编写计算各层径流量的函数。

  3. 绘制图形:通过JFreeChart库,绘制径流过程线或柱状图,展示模型计算结果。

到此,用java语言JFreeChart库来绘制水文图形完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值