【问题标题】:Changing the shapes of points in scatter plot改变散点图中点的形状
【发布时间】:2011-10-03 16:01:53
【问题描述】:

我有数千个点要绘制在 JFreeChart 散点图上。 现在的问题是我的程序正在用“正方形”绘制点,但我需要一些帮助来了解如何将点的Shape 从“正方形”更改为“点/圆”。 任何帮助将不胜感激。

//*我正在使用 ShapeUtilities,但是当我用于 XYItemRenderer/XYDotRenderer 时,它不会将点的形状更改为“DaigonalCross”--如果代码中有任何错误,请更正.. *///

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Shape;
import java.util.*;
import javax.swing.JPanel;
import org.jfree.chart.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYDotRenderer;
import org.jfree.data.xy.XYDataset;
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.util.ShapeUtilities;

public class SPlotfinal extends ApplicationFrame {

    public SPlotfinal(String s) {
        super(s);
        JPanel jpanel = createDemoPanel();
        jpanel.setPreferredSize(new Dimension(500, 270));
        setContentPane(jpanel);
    }

    public static JPanel createDemoPanel() {

        JFreeChart jfreechart = ChartFactory.createScatterPlot("Scatter Plot Demo",
            "X", "Y", samplexydataset2(), PlotOrientation.VERTICAL, true, true, false);
        Shape cross = ShapeUtilities.createDiagonalCross(3, 1);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        XYItemRenderer renderer = xyPlot.getRenderer();
        renderer.setBaseShape(cross);
        renderer.setBasePaint(Color.red);
        //changing the Renderer to XYDotRenderer
        //xyPlot.setRenderer(new XYDotRenderer());
        XYDotRenderer xydotrenderer = new XYDotRenderer();
        xyPlot.setRenderer(xydotrenderer);
        xydotrenderer.setSeriesShape(0, cross);

        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);

        return new ChartPanel(jfreechart);
    }

    private static XYDataset samplexydataset2() {
        int cols = 20;
        int rows = 20;
        double[][] values = new double[cols][rows];

        XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
        XYSeries series = new XYSeries("Random");
        Random rand = new Random();
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                double x = Math.round(rand.nextDouble() * 500);
                double y = Math.round(rand.nextDouble() * 500);

                series.add(x, y);
            }
        }
        xySeriesCollection.addSeries(series);
        return xySeriesCollection;
    }

    public static void main(String args[]) {
        SPlotfinal scatterplotdemo4 = new SPlotfinal("Scatter Plot Demo 4");
        scatterplotdemo4.pack();
        RefineryUtilities.centerFrameOnScreen(scatterplotdemo4);
        scatterplotdemo4.setVisible(true);
    }
}

【问题讨论】:

标签: java jfreechart


【解决方案1】:

ScatterRendererAbstractRenderer 继承 getItemShape()。您可以覆盖 getItemShape() 以提供您自己的形状。

附录:这种方法的一个优点是您可以为每个系列中的每个项目指定一个Shape

附录:要使用ShapeUtilities.createDiagonalCross(),请执行以下操作:

Shape cross = ShapeUtilities.createDiagonalCross(3, 1);
plot = (XYPlot) chart.getPlot();
renderer = plot.getRenderer();
renderer.setSeriesShape(0, cross);

附录:只需切换到setSeriesShape()。另外,请跳过XYDotRendererMath.round()

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Shape;
import java.util.*;
import javax.swing.JPanel;
import org.jfree.chart.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYDataset;
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.util.ShapeUtilities;

public class SPlotfinal extends ApplicationFrame {

    public SPlotfinal(String s) {
        super(s);
        JPanel jpanel = createDemoPanel();
        jpanel.setPreferredSize(new Dimension(640, 480));
        add(jpanel);
    }

    public static JPanel createDemoPanel() {
        JFreeChart jfreechart = ChartFactory.createScatterPlot(
            "Scatter Plot Demo", "X", "Y", samplexydataset2(),
            PlotOrientation.VERTICAL, true, true, false);
        Shape cross = ShapeUtilities.createDiagonalCross(3, 1);
        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        XYItemRenderer renderer = xyPlot.getRenderer();
        renderer.setSeriesShape(0, cross);
        renderer.setSeriesPaint(0, Color.red);
        return new ChartPanel(jfreechart);
    }

    private static XYDataset samplexydataset2() {
        int cols = 20;
        int rows = 20;
        double[][] values = new double[cols][rows];
        XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
        XYSeries series = new XYSeries("Random");
        Random rand = new Random();
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                double x = rand.nextGaussian();
                double y = rand.nextGaussian();
                series.add(x, y);
            }
        }
        xySeriesCollection.addSeries(series);
        return xySeriesCollection;
    }

    public static void main(String args[]) {
        SPlotfinal scatterplotdemo4 = new SPlotfinal("Scatter Plot Demo 4");
        scatterplotdemo4.pack();
        RefineryUtilities.centerFrameOnScreen(scatterplotdemo4);
        scatterplotdemo4.setVisible(true);
    }
}

【讨论】:

  • 你能把上面“ScatterPlotDemo”的代码贴出来吗,这正是我要找的......谢谢
  • 太长了;我已经改编了你上面的例子。
  • 太好了..非常感谢您编辑代码;)..如果可能的话,您能否发布上一张图的代码-“ScatterPlotDemo”,它具有所有形状..谢谢跨度>
  • 额外的形状由上面提到的DefaultDrawingSupplier 自动提供,每次您将另一个系列添加到您的XYSeriesCollection 时。请考虑通过单击左侧的空复选标记来接受此答案。
【解决方案2】:

您可以获取绘图(对于此示例,它是一个 XYPlot),然后是渲染器并像这样更改基本形状:

// 5x5 red pixel circle
Shape shape  = new Ellipse2D.Double(0,0,5,5);
XYPlot xyPlot = (XYPlot) jFreeCHart.getPlot();
XYItemRenderer renderer = xyPlot.getRenderer();
renderer.setBaseShape(shape);
renderer.setBasePaint(Color.red);

// set only shape of series with index i
renderer.setSeriesShape(i, shape);

您可以更改更多内容,例如轮廓绘制/描边

【讨论】:

  • 很遗憾,这不起作用,因为 setBaseShape()setSeriesShape() 似乎未实现。
  • 幸运的是,基类中有可用的setSeriesShape()AbstractRenderer
  • 我用你的代码试过了...我还有其他问题。我在“Class ShapeUtilities”中有一个方法 createDiagonalCross(float l, float t),它为点创建对角十字形状,如何我可以在上面的代码中使用这个方法吗?需要帮助吗?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 2015-07-12
  • 2016-05-17
  • 2016-03-22
  • 2013-12-19
相关资源
最近更新 更多