在放大的散点图中获取区域或元素 [英] Get Area or Elements in zoomed Scatterplot

查看:18
本文介绍了在放大的散点图中获取区域或元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

import java.awt.Color;导入 java.awt.Dimension;导入 org.jfree.chart.ChartPanel;导入 org.jfree.chart.event.AxisChangeEvent;导入 org.jfree.chart.event.AxisChangeListener;导入 org.jfree.chart.plot.PlotOrientation;导入 org.jfree.chart.plot.XYPlot;导入 org.jfree.data.xy.XYSeries;导入 org.jfree.data.xy.XYSeriesCollection;导入 org.jfree.ui.ApplicationFrame;导入 org.jfree.ui.RefineryUtilities;导入 org.jfree.chart.ChartFactory;导入 org.jfree.chart.JFreeChart;公共类 ScatterExample 扩展 ApplicationFrame 实现 AxisChangeListener {/*** 创建一个新的演示实例.* @param title 框架标题.*/私人 XYSeriesCollection 数据集;私人 JFreeChart 图表;公共散点示例(字符串标题){超级(标题);数据集 = createSampleXYDataset();图表 = ChartFactory.createScatterPlot("Scatterplot Demo",//图表标题"X",//域轴标签"Y",//范围轴标签数据集,//数据PlotOrientation.VERTICAL,//方向true,//包括图例true,//工具提示?false//网址?);//自定义图表chart.setBackgroundPaint(Color.white);XYPlot 图 = 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));设置内容面板(图表面板);}私人 XYSeriesCollection createSampleXYDataset() {XYSeriesCollection d = 新的 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);返回d;}/*** 演示应用程序的起点.* @param args 被忽略.*/公共静态无效主(字符串 [] args){ScatterExample demo = new ScatterExample("散点图演示");演示.pack();RefineryUtilities.centerFrameOnScreen(demo);演示.setVisible(真);}@覆盖公共无效axisChanged(AxisChangeEvent事件){if (event.getAxis().equals(chart.getXYPlot().getRangeAxis())){double rangeLow = chart.getXYPlot().getRangeAxis().getLowerBound();double rangeUp = chart.getXYPlot().getRangeAxis().getUpperBound();System.out.println("RangeAxis 新范围从 "+rangeLow+" 到 "+rangeUp);}别的 {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);}}}}

解决方案

海报通过

import java.awt.BorderLayout;导入 java.awt.Dimension;导入 java.awt.EventQueue;导入 java.awt.Rectangle;导入 java.text.DecimalFormat;导入 java.text.NumberFormat;导入 java.util.Random;导入 javax.swing.JButton;导入 javax.swing.JFrame;导入 javax.swing.JLabel;导入 javax.swing.JPanel;导入 javax.swing.JScrollPane;导入 javax.swing.JTable;导入 javax.swing.JToolBar;导入 javax.swing.table.DefaultTableCellRenderer;导入 javax.swing.table.DefaultTableModel;导入 org.jfree.chart.ChartPanel;导入 org.jfree.chart.event.AxisChangeEvent;导入 org.jfree.chart.event.AxisChangeListener;导入 org.jfree.chart.plot.PlotOrientation;导入 org.jfree.chart.plot.XYPlot;导入 org.jfree.data.xy.XYSeries;导入 org.jfree.data.xy.XYSeriesCollection;导入 org.jfree.chart.ChartFactory;导入静态 org.jfree.chart.ChartPanel.*;导入 org.jfree.chart.JFreeChart;导入 org.jfree.chart.axis.Axis;导入 org.jfree.chart.axis.ValueAxis;公共最终类 ScatterExample 实现 AxisChangeListener {私有静态最终 int N = 32;//每个系列的数据点私有静态最终 int R = 10;//初始轴边界私人最终随机随机=新随机();私人图表面板图表面板 = 新图表面板(空,假){@覆盖公共维度 getPreferredSize() {返回新维度(400, 400);}};私有最终 DefaultTableModel 模型 = 新 DefaultTableModel(new String[]{轴"、下限"、上限"}, 0) {@覆盖public boolean isCellEditable(int row, int column) {返回假;}};私有最终 JTable 表 = 新 JTable(模型){@覆盖公共类getColumnClass(int 列) {开关(列){案例0:返回 String.class;情况1:返回 Double.class;案例2:返回 Double.class;默认:返回 String.class;}}@覆盖公共维度 getPreferredScrollableViewportSize() {返回新维度(250, 400);}};公共静态无效主(字符串 [] args){EventQueue.invokeLater(new ScatterExample()::display);}私人无效显示(){XYSeriesCollection 数据集 = createSampleXYDataset();JFreeChart 图表 = ChartFactory.createScatterPlot("Scatterplot",//图表标题"X",//域轴标签Y",//范围轴标签数据集,//数据PlotOrientation.VERTICAL,//方向true,//包括图例?true,//工具提示?false//网址?);XYPlot 图 = 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() {{setHorizo​​ntalAlignment(JLabel.RIGHT);}NumberFormat f = new DecimalFormat("#.00");@覆盖protected void setValue(Object value) {setText((value == null) ? "" : f.format(value));}});JFrame f = new JFrame(轴范围示例");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);}私人 XYSeriesCollection createSampleXYDataset() {XYSeriesCollection d = 新的 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);返回d;}@覆盖公共无效axisChanged(AxisChangeEvent事件){轴已更改 = event.getAxis();ValueAxis domainAxis = chartPanel.getChart().getXYPlot().getDomainAxis();ValueAxis rangeAxis = chartPanel.getChart().getXYPlot().getRangeAxis();if (changed.equals(domainAxis)) {双下 = domainAxis.getLowerBound();double upper = domainAxis.getUpperBound();model.addRow(new Object[]{Domain",lower,upper});}if (changed.equals(rangeAxis)) {双下 = rangeAxis.getLowerBound();double upper = rangeAxis.getUpperBound();model.addRow(new Object[]{Range",lower,upper});}int last = table.getModel().getRowCount() - 1;矩形 r = table.getCellRect(last, 0, true);table.scrollRectToVisible(r);}//@see https://stackoverflow.com/a/41544007/230513私人 JPanel createControls() {JPanel 面板 = new JPanel();JToolBar toolBar = new JToolBar();toolBar.add(createButton(放大",ZOOM_IN_BOTH_COMMAND));toolBar.add(createButton(放大 X", ZOOM_IN_DOMAIN_COMMAND));toolBar.add(createButton("Zoom In Y", ZOOM_IN_RANGE_COMMAND));toolBar.add(createButton(缩小",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));面板.添加(工具栏);返回面板;}私有 JButton createButton(字符串名称,字符串命令){final JButton b = new JButton(name);b.setActionCommand(命令);b.addActionListener(chartPanel);返回 b;}}

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);
        }
    }   
}
}

解决方案

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.

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;
    }
}

这篇关于在放大的散点图中获取区域或元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆