我将JFreeChart与Java配合使用,以使用箱线图评估实验结果。我想更改离群值和远端条目的颜色和形状。
这是我使用常规BoxAndWhiskerRenderer时当前绘制的样子:
我这样设置渲染器:
BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
renderer.setFillBox(true);
renderer.setSeriesPaint(0, Color.DARK_GRAY);
renderer.setSeriesPaint(1, Color.LIGHT_GRAY);
renderer.setSeriesOutlinePaint(0, Color.BLACK);
renderer.setSeriesOutlinePaint(1, Color.BLACK);
renderer.setUseOutlinePaintForWhiskers(true);
Font legendFont = new Font("SansSerif", Font.PLAIN, 15);
renderer.setLegendTextFont(0, legendFont);
renderer.setLegendTextFont(1, legendFont);
renderer.setMeanVisible(false);
在这里,我无法更改异常值的颜色和形状。我希望它们是黑色的,而不是其系列的颜色。我希望它们看起来像小十字架,而不是这些大的空圆圈。
同样,也没有显示任何Farout值,并且似乎其中一个异常值被切除了。
然后,我找到了
ExtendedBoxAndWhiskerRenderer
,它可以编辑离群值和离群值的颜色和形状。看起来像这样:我像以前一样设置了渲染器,但是我添加了两行来设置离群值和远场条目的颜色:
renderer.setOutlierPaint(Color.BLACK); renderer.setFaroutPaint(Color.LIGHT_GRAY);
我还通过将扩展渲染器实现中的圆弧半径减小到1.0而不是2.0来测试离群值的形状:
private Shape createEllipse(Point2D point, double oRadius) {
Ellipse2D dot = new Ellipse2D.Double(point.getX(), point.getY(), oRadius*1.0, oRadius*1.0);
return dot;
}
但是,我也不太喜欢这些情节。我的情节的晶须/轮廓线不再是黑色的,即使我将其设置为黑色。即使我将其设置为不可见,均值也再次可见。如此数量庞大的离群值看起来有些荒谬,这让我想知道为什么在使用普通渲染器的情节中根本没有任何缺点。
如果有人可以帮助我解决这些较小的外观问题,那将非常好。否则,我将以当前具有奇怪的异常值和缺少的异常值的情节进行绘图...
最佳答案
尽管ExtendedBoxAndWhiskerRenderer
是示例性的,但它有些过时,并且其许多功能已合并到主线版本中。您的实验表明旧的渲染器和新的数据集不兼容。
因为异常值渲染方法是私有的,所以另一种方法是重写相关的draw*Item()
方法,并让其调用您自己的变体。您需要根据需要使用公共访问器来概括现有代码。概括而言,以下变体使用Color.black
进行了演示,如下所示。
plot.setRenderer(new BoxAndWhiskerRenderer() {
@Override
public void drawVerticalItem(Graphics2D g2, …) {
// existing code that calls the methods below
}
private void drawEllipse(Point2D point, double oRadius, Graphics2D g2) {
Paint temp = g2.getPaint();
g2.setColor(Color.black);
Ellipse2D dot = new Ellipse2D.Double(point.getX() + oRadius / 2,
point.getY(), oRadius, oRadius);
g2.draw(dot);
g2.setPaint(temp);
}
private void drawHighFarOut(double aRadius, Graphics2D g2, double xx,
double m) {
Paint temp = g2.getPaint();
g2.setColor(Color.black);
double side = aRadius * 2;
g2.draw(new Line2D.Double(xx - side, m + side, xx + side, m + side));
g2.draw(new Line2D.Double(xx - side, m + side, xx, m));
g2.draw(new Line2D.Double(xx + side, m + side, xx, m));
g2.setPaint(temp);
}
}