在放大的散点图中获取区域或元素
Posted
技术标签:
【中文标题】在放大的散点图中获取区域或元素【英文标题】:Get Area or Elements in zoomed Scatterplot 【发布时间】:2011-11-07 11:15:30 【问题描述】:我遇到了以下问题。我想放大散点图,然后选择所有显示的元素。
在放大的散点图中以某种方式获得显示区域就足够了。从这个区域的范围内,我可以确定哪些元素显示在该区域中,哪些不显示。
\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);
【问题讨论】:
通过实现AxisChangeListener接口,发布后立即找到解决方案 【参考方案1】:发帖人通过让ScatterExample
类实现AxisChangeListener
接口找到了解决方案。 example 已更新为 version 1.5。它还添加了一个表格来显示轴绑定更改的历史记录。该图显示了zooming, panning 并单击缩放命令按钮,Zoom In 到 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://***.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;
【讨论】:
以上是关于在放大的散点图中获取区域或元素的主要内容,如果未能解决你的问题,请参考以下文章
power bi怎么做散点图啊?如何利用power bi绘制散点图??
R语言ggplot2可视化:ggplot2可视化分组散点图并使用geom_smooth函数在散点图图中为不同的散点簇添加对应的回归曲线