我想用Java制作一个离散信号图,就像在matlab中使用stem()命令时一样,这样当给它一个x轴数组和一个y轴数组时,它就像一个散点图绘制一条与 x 轴相连的垂直线。
我尝试使用 JFreeChart 来执行此操作,但它没有专门的离散图。我最接近的是要求 ChatGPT 制作散点图并将线条连接到底部,它给了我以下代码:
package z;
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.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.chart.ui.RectangleInsets;
import org.jfree.data.xy.DefaultXYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import java.awt.Color;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.util.Random;
import javax.swing.SwingUtilities;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
public class ScatterPlotWithLines extends ApplicationFrame {
public ScatterPlotWithLines(String title) {
super(title);
// Create a dataset with 10 random data points
XYSeriesCollection dataset = createScatterDataset(10);
// Create the scatter plot
JFreeChart chart = ChartFactory.createScatterPlot(
"Scatter Plot with Lines",
"X-Axis Label",
"Y-Axis Label",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
// Customize the plot and renderer for scatter points (optional)
XYPlot plot = (XYPlot) chart.getPlot();
XYItemRenderer renderer = plot.getRenderer();
// Customize the renderer for scatter points (e.g., change the shape and color of points)
Shape pointShape = new Ellipse2D.Double(-3, -3, 6, 6); // Example shape
renderer.setSeriesShape(0, pointShape);
renderer.setSeriesPaint(0, Color.blue);
// Create a dataset for lines connecting the data points to the x-axis
DefaultXYDataset lineDataset = createLineDataset(dataset);
// Create a renderer for the lines
XYItemRenderer lineRenderer = new XYLineAndShapeRenderer(true, false);
lineRenderer.setSeriesPaint(0, Color.red); // Line color
plot.setDataset(1, lineDataset); // Add the line dataset to the plot
plot.setRenderer(1, lineRenderer); // Set the line renderer for the new dataset
// Set margin for the plot
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
// Create a ChartPanel and add it to the frame
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(800, 600));
setContentPane(chartPanel);
}
private XYSeriesCollection createScatterDataset(int numPoints) {
XYSeriesCollection dataset = new XYSeriesCollection();
XYSeries series = new XYSeries("Scatter Plot");
// Generate random data points for the series
Random rand = new Random();
for (int i = 0; i < numPoints; i++) {
double x = rand.nextDouble() * 10;
double y = rand.nextDouble() * 10;
series.add(x, y);
}
dataset.addSeries(series);
return dataset;
}
private DefaultXYDataset createLineDataset(XYSeriesCollection scatterDataset) {
DefaultXYDataset lineDataset = new DefaultXYDataset();
// Create lines connecting data points to the x-axis
for (int i = 0; i < scatterDataset.getSeriesCount(); i++) {
XYSeries scatterSeries = scatterDataset.getSeries(i);
double[][] lineData = new double[2][scatterSeries.getItemCount() * 2];
for (int j = 0; j < scatterSeries.getItemCount(); j++) {
double x = scatterSeries.getX(j).doubleValue();
double y = scatterSeries.getY(j).doubleValue();
// Add the data point
lineData[0][j * 2] = x;
lineData[1][j * 2] = y;
// Connect to the x-axis
lineData[0][j * 2 + 1] = x;
lineData[1][j * 2 + 1] = 0;
}
lineDataset.addSeries("Lines", lineData);
}
return lineDataset;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
ScatterPlotWithLines example = new ScatterPlotWithLines("Scatter Plot with Lines");
example.pack();
example.setDefaultCloseOperation(ApplicationFrame.EXIT_ON_CLOSE);
example.setVisible(true);
});
}
}
并且它有效,有点:
我知道它制作了不同的数据集并将点连接起来,但是是否可以仅使用垂直线?我知道我可以使用其他语言(例如 Python 和 MatLab)轻松地做到这一点,我只是想知道是否可以用 Java 做到这一点。
正如@Ahmed AEK comments,您可以调整数据集以“使其看起来更像stem”。还要考虑,
HighLowRenderer
,适合连续数据; setDraw [Close|Open] Ticks()
方法控制刻度线可见性。
MinMaxCategoryRenderer
,适用于类别数据;图标可以替换为自定义实现,如此处和此处所示。