JFreeChart 禁用 XYPlot 的垂直灰色区域

JFreeChart disable vertical gray areas of XYPlot

下面的代码绘制了一个图表,其中包含与备用域刻度对应的不需要的垂直灰色区域(条纹)。

我曾尝试将它们从图表中删除以获得白色背景图,但未成功。

我一直在搜索 XYPlot 或 NumberAxis 的方法(最后尝试设置为空 xyplot.setDomainTickBandPaint(null);xyplot.setRangeTickBandPaint(null);),但我对 JFreeChart 的经验不足,不知道该使用什么方法.

这是上图的代码:

public class MyPlotChart {
    private static Color MetalColor = new Color(255, 152, 0);
    static double[] yData = new double[] { 49.68, 49.18, 49.78, 49.65, 48.94, 50.02, 50.27};
    static String[] labels = new String[] { "2021-10-28", "2021-10-29", "2021-11-01", "2021-11-02", "2021-11-03", "2021-11-04", "2021-11-05"};

    public static void plot(String metal, int samples) throws IOException {

        XYSeries series = new XYSeries(metal);
        int i = 0;
        for (i = 0; i < yData.length; i++) {
            series.add(i, yData[i]);
        }
        
        XYDataset dataset = new XYSeriesCollection(series);
        NumberAxis domain = new SymbolAxis(null, labels);

        NumberAxis verticalAxis = new NumberAxis(null);
        verticalAxis.setAutoRangeIncludesZero(false);
        
        domain.setTickUnit(new NumberTickUnit(1.0));
        domain.setMarkerBand(null);
        
        double vericalTickUnit = (series.getMaxY() - series.getMinY()) / 5;
        NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
        numberFormat.setRoundingMode(RoundingMode.HALF_DOWN);
        numberFormat.setMinimumFractionDigits(2);
        numberFormat.setMaximumFractionDigits(2);
        NumberTickUnit nt = new NumberTickUnit(vericalTickUnit, numberFormat);
        verticalAxis.setTickUnit(nt);
        verticalAxis.setAutoRange(true);
        verticalAxis.setRange(new Range(series.getMinY()-0.1, series.getMaxY()+0.1));
        verticalAxis.setTickMarksVisible(true);
        verticalAxis.setTickMarkInsideLength(3f);
        
        
        XYSplineRenderer r = new XYSplineRenderer(10);
        r.setSeriesPaint(0, MetalColor);
        r.setDefaultShapesVisible(false);
        r.setSeriesStroke(0, new BasicStroke(3.0f));
        
        XYPlot xyplot = new XYPlot(dataset, domain, verticalAxis, r);
        xyplot.getDomainAxis().setVerticalTickLabels(true);
        xyplot.setDomainGridlinesVisible(false);
        xyplot.setBackgroundImage(null);
        xyplot.setBackgroundPaint(Color.WHITE);
        Font font = xyplot.getDomainAxis().getTickLabelFont();
        Font fontnew = new Font(font.getName(), Font.BOLD, 14);
        xyplot.getDomainAxis().setTickLabelFont(fontnew);
        xyplot.getRangeAxis().setTickLabelFont(fontnew);

        JFreeChart chart = new JFreeChart(xyplot);
        chart.removeLegend();//Remove legend
        chart.setBackgroundPaint(Color.WHITE);
        String fileName = "myChart"+metal+samples+"TEST.png";
        ChartUtils.saveChartAsPNG(new File(fileName), chart, 600, 600);
    }
       
    public static void main(String[] args) throws IOException {
         MyPlotChart.plot("metal", 7);
    }
}

正如评论中所建议的,我选择使用 DateAxis,它不实现交替背景,并且在数据与时间相关时也能更准确地处理刻度标签。

附上代码和得到的图:

public class MyPlotChart {
    private static Color MetalColor = new Color(255, 152, 0);
    static double[] yData = new double[] { 49.68, 49.18, 49.78, 49.65, 48.94, 50.02, 50.27 };
    static String[] labels = new String[] { "2021-10-28", "2021-10-29", "2021-11-01", "2021-11-02", "2021-11-03",
            "2021-11-04", "2021-11-05" };
    public static void plot(String metal, int samples) throws IOException, ParseException {
        SimpleDateFormat dateformatyyyy_MM_dd = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dateformatdd_MM_yyyy = new SimpleDateFormat("dd-MM-yyyy");

        XYSeries series = new XYSeries(metal);

        for (int i = 0; i < yData.length; i++) {
            Date date = dateformatyyyy_MM_dd.parse(labels[i]);
            series.add(date.getTime(), yData[i]);
        }

        //Configure Vertical Axis
        NumberAxis verticalAxis = new NumberAxis(null);
        NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
        numberFormat.setRoundingMode(RoundingMode.HALF_DOWN);
        numberFormat.setMinimumFractionDigits(2);
        numberFormat.setMaximumFractionDigits(2);
        double vericalTickUnit = (series.getMaxY() - series.getMinY()) / 7;
        NumberTickUnit nt = new NumberTickUnit(vericalTickUnit, numberFormat);
        verticalAxis.setTickUnit(nt);
        double percentOverRange = 0.05;// 2%
        double initalRange = series.getMaxY() - series.getMinY();
        double increase = initalRange * percentOverRange;
        verticalAxis.setRange(new Range(series.getMinY()-increase, series.getMaxY()+increase));
        verticalAxis.setAutoRange(true);
        verticalAxis.setAutoRangeIncludesZero(false);
        verticalAxis.setTickMarksVisible(true);
        verticalAxis.setTickMarkInsideLength(3f);
        
        //Configure Domain Axis
        DateAxis domainAxis = new DateAxis(null);
        domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY, 1, dateformatdd_MM_yyyy));

        //Configure Renderer
        XYSplineRenderer r = new XYSplineRenderer(10);
        r.setSeriesPaint(0, MetalColor);
        r.setDefaultShapesVisible(false);
        r.setSeriesStroke(0, new BasicStroke(3.0f));
        
        XYDataset dataset = new XYSeriesCollection(series);
        XYPlot xyplot = new XYPlot(dataset, domainAxis, verticalAxis, r);
        xyplot.getDomainAxis().setVerticalTickLabels(true);
        xyplot.setDomainGridlinesVisible(false);
        xyplot.setBackgroundImage(null);
        xyplot.setBackgroundPaint(Color.WHITE);
        Font font = xyplot.getDomainAxis().getTickLabelFont();
        Font fontnew = new Font(font.getName(), Font.BOLD, 14);
        xyplot.getDomainAxis().setTickLabelFont(fontnew);
        xyplot.getRangeAxis().setTickLabelFont(fontnew);

        JFreeChart chart = new JFreeChart(xyplot);
        chart.removeLegend();// Remove legend
        chart.setBackgroundPaint(Color.WHITE);
        String fileName = "myChart" + metal + samples + "TEST.png";
        ChartUtils.saveChartAsPNG(new File(fileName), chart, 600, 600);
    }
    public static void main(String[] args) throws IOException, ParseException {
        MyPlotChart.plot("metal", 7);
    }
}