获取缩放散点图中的面积或元素

发布于 2024-12-02 09:27:50 字数 3341 浏览 1 评论 0原文

我有以下问题。我想放大散点图,然后选择所有显示的元素。

以某种方式获得放大散点图中的显示区域就足够了。从该区域的范围我可以确定哪些元素显示在该区域中,哪些不显示。

\edit:找到解决方案(实现 AxisChangeListener 接口)

import java.awt.Color;
import java.awt.Dimension;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.event.AxisChangeListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.chart.ChartFactory;  
import org.jfree.chart.JFreeChart; 


public class ScatterExample extends ApplicationFrame implements AxisChangeListener {
/**
 * Creates a new demo instance.
 * @param title the frame title. 
 */

private XYSeriesCollection dataset;
private JFreeChart chart;


public ScatterExample(String title) { 
    super(title);

    dataset = createSampleXYDataset();

    chart = ChartFactory.createScatterPlot(
            "Scatterplot Demo", // chart title
            "X", // domain axis label
            "Y", // range axis label
            dataset,  // data
            PlotOrientation.VERTICAL, // orientation
            true, // include legend
            true, // tooltips? 
            false // URLs?

    ); 
    //customize chart
    chart.setBackgroundPaint(Color.white); 
    XYPlot plot = chart.getXYPlot(); 
    plot.setBackgroundPaint(Color.lightGray); 
    plot.setRangeGridlinePaint(Color.white);

    plot.getRangeAxis().setRange(0.0, 10.0);
    plot.getRangeAxis().addChangeListener(this);
    plot.getDomainAxis().setRange(0.0, 10.0);
    plot.getDomainAxis().addChangeListener(this);

    ChartPanel chartPanel = new ChartPanel(chart, false); 
    chartPanel.setPreferredSize(new Dimension(500, 500)); 
    setContentPane(chartPanel); 
}

private XYSeriesCollection createSampleXYDataset() {
    XYSeriesCollection d = new XYSeriesCollection();
    XYSeries ser = new XYSeries("Series 1");
    XYSeries ser2 = new XYSeries("Series 2");

    ser.add(1.0,2.0);
    ser.add(2.0,2.0);
    ser2.add(3.0,2.0);
    ser.add(3.0,3.0);
    ser2.add(2.0,5.0);
    ser.add(1.0,2.0);
    ser.add(3.0,7.0);
    ser2.add(4.0,4.0);

    d.addSeries(ser);
    d.addSeries(ser2);

    return d;
}

/**
 * Starting point for the demonstration application. 
 * @param args ignored. 
 */

public static void main(String[] args) {
    ScatterExample demo = new ScatterExample("Scatterplot Demo"); 
    demo.pack(); 
    RefineryUtilities.centerFrameOnScreen(demo); 
    demo.setVisible(true);
}

@Override
public void axisChanged(AxisChangeEvent event) {
    if (event.getAxis().equals(chart.getXYPlot().getRangeAxis())){
        double rangeLow = chart.getXYPlot().getRangeAxis().getLowerBound();
        double rangeUp = chart.getXYPlot().getRangeAxis().getUpperBound();

        System.out.println("RangeAxis new range from "+rangeLow+" to "+rangeUp);
    }
    else {
        if (event.getAxis().equals(chart.getXYPlot().getDomainAxis())){
            double domainLow = chart.getXYPlot().getDomainAxis().getLowerBound();
            double domainUp = chart.getXYPlot().getDomainAxis().getUpperBound();

            System.out.println("DomainAxis new range from "+domainLow+" to "+domainUp);
        }
    }   
}
}

I've got the following problem. I want to zoom-in a Scatterplot and then select all the displayed elements.

It would be sufficient to somehow get the displayed area in the zoomed-in Scatterplot. From the range of this area i could determine which elements are displayed in the area and which are not.

\edit: Found the Solution (Implementing AxisChangeListener Interface)

import java.awt.Color;
import java.awt.Dimension;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.event.AxisChangeListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.chart.ChartFactory;  
import org.jfree.chart.JFreeChart; 


public class ScatterExample extends ApplicationFrame implements AxisChangeListener {
/**
 * Creates a new demo instance.
 * @param title the frame title. 
 */

private XYSeriesCollection dataset;
private JFreeChart chart;


public ScatterExample(String title) { 
    super(title);

    dataset = createSampleXYDataset();

    chart = ChartFactory.createScatterPlot(
            "Scatterplot Demo", // chart title
            "X", // domain axis label
            "Y", // range axis label
            dataset,  // data
            PlotOrientation.VERTICAL, // orientation
            true, // include legend
            true, // tooltips? 
            false // URLs?

    ); 
    //customize chart
    chart.setBackgroundPaint(Color.white); 
    XYPlot plot = chart.getXYPlot(); 
    plot.setBackgroundPaint(Color.lightGray); 
    plot.setRangeGridlinePaint(Color.white);

    plot.getRangeAxis().setRange(0.0, 10.0);
    plot.getRangeAxis().addChangeListener(this);
    plot.getDomainAxis().setRange(0.0, 10.0);
    plot.getDomainAxis().addChangeListener(this);

    ChartPanel chartPanel = new ChartPanel(chart, false); 
    chartPanel.setPreferredSize(new Dimension(500, 500)); 
    setContentPane(chartPanel); 
}

private XYSeriesCollection createSampleXYDataset() {
    XYSeriesCollection d = new XYSeriesCollection();
    XYSeries ser = new XYSeries("Series 1");
    XYSeries ser2 = new XYSeries("Series 2");

    ser.add(1.0,2.0);
    ser.add(2.0,2.0);
    ser2.add(3.0,2.0);
    ser.add(3.0,3.0);
    ser2.add(2.0,5.0);
    ser.add(1.0,2.0);
    ser.add(3.0,7.0);
    ser2.add(4.0,4.0);

    d.addSeries(ser);
    d.addSeries(ser2);

    return d;
}

/**
 * Starting point for the demonstration application. 
 * @param args ignored. 
 */

public static void main(String[] args) {
    ScatterExample demo = new ScatterExample("Scatterplot Demo"); 
    demo.pack(); 
    RefineryUtilities.centerFrameOnScreen(demo); 
    demo.setVisible(true);
}

@Override
public void axisChanged(AxisChangeEvent event) {
    if (event.getAxis().equals(chart.getXYPlot().getRangeAxis())){
        double rangeLow = chart.getXYPlot().getRangeAxis().getLowerBound();
        double rangeUp = chart.getXYPlot().getRangeAxis().getUpperBound();

        System.out.println("RangeAxis new range from "+rangeLow+" to "+rangeUp);
    }
    else {
        if (event.getAxis().equals(chart.getXYPlot().getDomainAxis())){
            double domainLow = chart.getXYPlot().getDomainAxis().getLowerBound();
            double domainUp = chart.getXYPlot().getDomainAxis().getUpperBound();

            System.out.println("DomainAxis new range from "+domainLow+" to "+domainUp);
        }
    }   
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

计㈡愣 2024-12-09 09:27:50

发布者通过让 ScatterExample 类实现 AxisChangeListener< 找到了解决方案/代码> 接口。 示例已更新为版本 1.5。它还添加了一个表格来显示轴边界更改的历史记录。该图像显示了缩放、平移并单击缩放命令按钮放大的结果重置 Y

image

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.event.AxisChangeListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.chart.ChartFactory;
import static org.jfree.chart.ChartPanel.*;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.Axis;
import org.jfree.chart.axis.ValueAxis;

public final class ScatterExample implements AxisChangeListener {

    private static final int N = 32; // data points per series
    private static final int R = 10; // initial axis bounds
    private final Random RANDOM = new Random();
    private ChartPanel chartPanel = new ChartPanel(null, false) {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    };
    private final DefaultTableModel model = new DefaultTableModel(
        new String[]{"Axis", "lower bound", "upper bound"}, 0) {
        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    };
    private final JTable table = new JTable(model) {

        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
                case 0:
                    return String.class;
                case 1:
                    return Double.class;
                case 2:
                    return Double.class;
                default:
                    return String.class;
            }
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(250, 400);
        }
    };

    public static void main(String[] args) {
        EventQueue.invokeLater(new ScatterExample()::display);
    }

    private void display() {
        XYSeriesCollection dataset = createSampleXYDataset();
        JFreeChart chart = ChartFactory.createScatterPlot(
            "Scatterplot", // chart title
            "X", // domain axis label
            "Y", // range axis label
            dataset, // data
            PlotOrientation.VERTICAL, // orientation
            true, // include legend?
            true, // tooltips? 
            false // URLs?
        );
        XYPlot plot = chart.getXYPlot();
        plot.setDomainPannable(true);
        plot.getDomainAxis().setRange(-R, R);
        plot.getDomainAxis().addChangeListener(this);
        plot.setRangePannable(true);
        plot.getRangeAxis().setRange(-R, R);
        plot.getRangeAxis().addChangeListener(this);

        chartPanel.setChart(chart);
        table.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() {
            {
                setHorizontalAlignment(JLabel.RIGHT);
            }
            NumberFormat f = new DecimalFormat("#.00");

            @Override
            protected void setValue(Object value) {
                setText((value == null) ? "" : f.format(value));
            }
        });

        JFrame f = new JFrame("Axis Range Example");
        f.add(chartPanel);
        f.add(createControls(), BorderLayout.SOUTH);
        f.add(new JScrollPane(table), BorderLayout.EAST);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private XYSeriesCollection createSampleXYDataset() {
        XYSeriesCollection d = new XYSeriesCollection();
        XYSeries series1 = new XYSeries("Series 1");
        XYSeries series2 = new XYSeries("Series 2");
        for (int i = 0; i < N; i++) {
            series1.add(RANDOM.nextGaussian(), RANDOM.nextGaussian());
            series2.add(RANDOM.nextGaussian(), RANDOM.nextGaussian());
        }
        d.addSeries(series1);
        d.addSeries(series2);
        return d;
    }

    @Override
    public void axisChanged(AxisChangeEvent event) {
        Axis changed = event.getAxis();
        ValueAxis domainAxis = chartPanel.getChart().getXYPlot().getDomainAxis();
        ValueAxis rangeAxis = chartPanel.getChart().getXYPlot().getRangeAxis();
        if (changed.equals(domainAxis)) {
            double lower = domainAxis.getLowerBound();
            double upper = domainAxis.getUpperBound();
            model.addRow(new Object[]{"Domain", lower, upper});
        }
        if (changed.equals(rangeAxis)) {
            double lower = rangeAxis.getLowerBound();
            double upper = rangeAxis.getUpperBound();
            model.addRow(new Object[]{"Range", lower, upper});
        }
        int last = table.getModel().getRowCount() - 1;
        Rectangle r = table.getCellRect(last, 0, true);
        table.scrollRectToVisible(r);
    }

    // @see https://stackoverflow.com/a/41544007/230513
    private JPanel createControls() {
        JPanel panel = new JPanel();
        JToolBar toolBar = new JToolBar();
        toolBar.add(createButton("Zoom In", ZOOM_IN_BOTH_COMMAND));
        toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND));
        toolBar.add(createButton("Zoom In Y", ZOOM_IN_RANGE_COMMAND));
        toolBar.add(createButton("Zoom Out", ZOOM_OUT_BOTH_COMMAND));
        toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND));
        toolBar.add(createButton("Zoom Out Y", ZOOM_OUT_RANGE_COMMAND));
        toolBar.add(createButton("Reset", ZOOM_RESET_BOTH_COMMAND));
        toolBar.add(createButton("Reset X", ZOOM_RESET_DOMAIN_COMMAND));
        toolBar.add(createButton("Reset Y", ZOOM_RESET_RANGE_COMMAND));
        panel.add(toolBar);
        return panel;
    }

    private JButton createButton(String name, String command) {
        final JButton b = new JButton(name);
        b.setActionCommand(command);
        b.addActionListener(chartPanel);
        return b;
    }
}

The poster found a solution to this by having the ScatterExample class implement the AxisChangeListener interface. The example has been updated to version 1.5. It also adds a table to display the history of the axis bound changes. The image shows the result of zooming, panning and clicking the zoom command buttons, Zoom In to Reset Y.

image

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.event.AxisChangeListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.chart.ChartFactory;
import static org.jfree.chart.ChartPanel.*;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.Axis;
import org.jfree.chart.axis.ValueAxis;

public final class ScatterExample implements AxisChangeListener {

    private static final int N = 32; // data points per series
    private static final int R = 10; // initial axis bounds
    private final Random RANDOM = new Random();
    private ChartPanel chartPanel = new ChartPanel(null, false) {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    };
    private final DefaultTableModel model = new DefaultTableModel(
        new String[]{"Axis", "lower bound", "upper bound"}, 0) {
        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    };
    private final JTable table = new JTable(model) {

        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
                case 0:
                    return String.class;
                case 1:
                    return Double.class;
                case 2:
                    return Double.class;
                default:
                    return String.class;
            }
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(250, 400);
        }
    };

    public static void main(String[] args) {
        EventQueue.invokeLater(new ScatterExample()::display);
    }

    private void display() {
        XYSeriesCollection dataset = createSampleXYDataset();
        JFreeChart chart = ChartFactory.createScatterPlot(
            "Scatterplot", // chart title
            "X", // domain axis label
            "Y", // range axis label
            dataset, // data
            PlotOrientation.VERTICAL, // orientation
            true, // include legend?
            true, // tooltips? 
            false // URLs?
        );
        XYPlot plot = chart.getXYPlot();
        plot.setDomainPannable(true);
        plot.getDomainAxis().setRange(-R, R);
        plot.getDomainAxis().addChangeListener(this);
        plot.setRangePannable(true);
        plot.getRangeAxis().setRange(-R, R);
        plot.getRangeAxis().addChangeListener(this);

        chartPanel.setChart(chart);
        table.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() {
            {
                setHorizontalAlignment(JLabel.RIGHT);
            }
            NumberFormat f = new DecimalFormat("#.00");

            @Override
            protected void setValue(Object value) {
                setText((value == null) ? "" : f.format(value));
            }
        });

        JFrame f = new JFrame("Axis Range Example");
        f.add(chartPanel);
        f.add(createControls(), BorderLayout.SOUTH);
        f.add(new JScrollPane(table), BorderLayout.EAST);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private XYSeriesCollection createSampleXYDataset() {
        XYSeriesCollection d = new XYSeriesCollection();
        XYSeries series1 = new XYSeries("Series 1");
        XYSeries series2 = new XYSeries("Series 2");
        for (int i = 0; i < N; i++) {
            series1.add(RANDOM.nextGaussian(), RANDOM.nextGaussian());
            series2.add(RANDOM.nextGaussian(), RANDOM.nextGaussian());
        }
        d.addSeries(series1);
        d.addSeries(series2);
        return d;
    }

    @Override
    public void axisChanged(AxisChangeEvent event) {
        Axis changed = event.getAxis();
        ValueAxis domainAxis = chartPanel.getChart().getXYPlot().getDomainAxis();
        ValueAxis rangeAxis = chartPanel.getChart().getXYPlot().getRangeAxis();
        if (changed.equals(domainAxis)) {
            double lower = domainAxis.getLowerBound();
            double upper = domainAxis.getUpperBound();
            model.addRow(new Object[]{"Domain", lower, upper});
        }
        if (changed.equals(rangeAxis)) {
            double lower = rangeAxis.getLowerBound();
            double upper = rangeAxis.getUpperBound();
            model.addRow(new Object[]{"Range", lower, upper});
        }
        int last = table.getModel().getRowCount() - 1;
        Rectangle r = table.getCellRect(last, 0, true);
        table.scrollRectToVisible(r);
    }

    // @see https://stackoverflow.com/a/41544007/230513
    private JPanel createControls() {
        JPanel panel = new JPanel();
        JToolBar toolBar = new JToolBar();
        toolBar.add(createButton("Zoom In", ZOOM_IN_BOTH_COMMAND));
        toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND));
        toolBar.add(createButton("Zoom In Y", ZOOM_IN_RANGE_COMMAND));
        toolBar.add(createButton("Zoom Out", ZOOM_OUT_BOTH_COMMAND));
        toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND));
        toolBar.add(createButton("Zoom Out Y", ZOOM_OUT_RANGE_COMMAND));
        toolBar.add(createButton("Reset", ZOOM_RESET_BOTH_COMMAND));
        toolBar.add(createButton("Reset X", ZOOM_RESET_DOMAIN_COMMAND));
        toolBar.add(createButton("Reset Y", ZOOM_RESET_RANGE_COMMAND));
        panel.add(toolBar);
        return panel;
    }

    private JButton createButton(String name, String command) {
        final JButton b = new JButton(name);
        b.setActionCommand(command);
        b.addActionListener(chartPanel);
        return b;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文