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

如何在Java中绘制类似Matlab stem()的离散信号图?

在Java中实现仅含垂直线的离散信号图(类似Matlab stem())

Java完全可以实现你需求的仅保留垂直线的离散信号图,无需依赖JFreeChart的现成工具类,以下提供两种可行方案:

方案一:自定义Swing组件直接绘制

通过Swing的Graphics2D API手动绘制垂直线,这种方式轻量且完全可控,步骤如下:

  • 创建继承JPanel的自定义组件,重写paintComponent方法
  • 将输入的x、y数组坐标映射到组件的像素坐标系
  • 遍历每个数据点,绘制从x轴(y=0对应的像素位置)到数据点的垂直线

示例代码:

import javax.swing.*;
import java.awt.*;
import java.util.Arrays;

public class StemPlotPanel extends JPanel {
    private double[] xData;
    private double[] yData;
    private static final int PADDING = 50;
    private static final int LINE_WIDTH = 2;

    public StemPlotPanel(double[] xData, double[] yData) {
        this.xData = xData;
        this.yData = yData;
        setPreferredSize(new Dimension(800, 600));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(new BasicStroke(LINE_WIDTH));

        // 计算坐标轴范围
        double minX = Arrays.stream(xData).min().orElse(0);
        double maxX = Arrays.stream(xData).max().orElse(10);
        double minY = Arrays.stream(yData).min().orElse(-5);
        double maxY = Arrays.stream(yData).max().orElse(5);
        // 确保包含y=0的x轴
        minY = Math.min(minY, 0);
        maxY = Math.max(maxY, 0);

        // 计算坐标映射比例
        double xScale = (getWidth() - 2 * PADDING) / (maxX - minX);
        double yScale = (getHeight() - 2 * PADDING) / (maxY - minY);

        // 绘制x轴和y轴
        int xAxisY = PADDING + (int) ((0 - minY) * yScale);
        int yAxisX = PADDING + (int) ((0 - minX) * xScale);
        g2d.drawLine(PADDING, xAxisY, getWidth() - PADDING, xAxisY);
        g2d.drawLine(yAxisX, PADDING, yAxisX, getHeight() - PADDING);

        // 绘制垂直线
        g2d.setColor(Color.BLUE);
        for (int i = 0; i < xData.length; i++) {
            double x = xData[i];
            double y = yData[i];
            // 转换为像素坐标
            int pixelX = PADDING + (int) ((x - minX) * xScale);
            int pixelY = PADDING + (int) ((maxY - y) * yScale);
            // 绘制从x轴到数据点的垂直线
            g2d.drawLine(pixelX, xAxisY, pixelX, pixelY);
        }
    }

    public static void main(String[] args) {
        double[] x = {1, 2, 3, 4, 5, 6};
        double[] y = {2, -1, 3, 0, -2, 1};
        JFrame frame = new JFrame("离散信号垂直线图");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new StemPlotPanel(x, y));
        frame.pack();
        frame.setVisible(true);
    }
}

方案二:基于JFreeChart扩展实现

如果你仍想使用JFreeChart,可以通过自定义数据集和渲染器来实现仅显示垂直线的效果:

  • 构造XYSeries时,为每个数据点添加两个坐标:(x, 0)和(x, y)
  • 使用XYLineAndShapeRenderer,关闭数据点形状的显示,只保留线段绘制

示例代码:

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import javax.swing.*;

public class JFreeChartStemPlot {
    public static void main(String[] args) {
        double[] x = {1, 2, 3, 4, 5, 6};
        double[] y = {2, -1, 3, 0, -2, 1};

        // 构造数据集:每个数据点对应(x,0)和(x,y)两个点
        XYSeries series = new XYSeries("离散信号");
        for (int i = 0; i < x.length; i++) {
            series.add(x[i], 0);
            series.add(x[i], y[i]);
        }
        XYSeriesCollection dataset = new XYSeriesCollection(series);

        // 创建图表并配置渲染器
        JFreeChart chart = ChartFactory.createXYLineChart(
                "离散信号垂直线图",
                "X轴",
                "Y轴",
                dataset
        );
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
        // 关闭数据点形状显示
        renderer.setSeriesShapesVisible(0, false);
        // 设置线段宽度
        renderer.setSeriesStroke(0, new java.awt.BasicStroke(2));

        // 显示图表
        JFrame frame = new JFrame("JFreeChart离散信号图");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ChartPanel(chart));
        frame.pack();
        frame.setVisible(true);
    }
}

两种方案都能实现仅保留垂直线的离散信号图,你可以根据项目依赖(是否使用JFreeChart)选择合适的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:16:01