我使用JFreeChart
绘制图表。我有带有点(0,0),(1,2),(2,5)的XYSeries,我想读取Y值,因为x = 1.5。
是否可以读取不在XYSeries中的点的值?我无法找到类似的主题。
答案 0 :(得分:2)
不直接支持此功能。在许多情况下它没有意义:没有数据可用于x = 1.5 。那里的值可能是1000.0,或-3.141。你不知道。
但是,您最有可能寻找线性插值。因此,实用方法是找到包含相应x值的间隔,并线性地内插y值。
有一些技术性的警告。例如。 XYSeries
可能没有排序,或者可能包含重复的x值,在这种情况下,给定的x值没有唯一的y值。但是现在,我们可以假设数据集没有这些属性。
以下是如何实施此示例的示例。请注意,这不是很有效。如果你必须计算许多中间值(也就是说,如果你打算经常调用interpolate
方法),那么创建一个允许查看的基于树的数据结构将是有益的。以O(logn)为间隔。
但是,如果这不是时间关键的(例如,如果您只打算在工具提示中显示该值),您可以插入如下值:
import java.util.List;
import org.jfree.data.xy.XYDataItem;
import org.jfree.data.xy.XYSeries;
public class XYInterpolation
{
public static void main(String[] args)
{
XYSeries s = new XYSeries("Series");
s.add(0,0);
s.add(1,2);
s.add(2,5);
double minX = -0.5;
double maxX = 3.0;
int steps = 35;
for (int i=0; i<=steps; i++)
{
double a = (double)i / steps;
double x = minX + a * (maxX - minX);
double y = interpolate(s, x);
System.out.printf("%8.3f : %8.3f\n", x, y);
}
}
private static double interpolate(XYSeries s, double x)
{
if (x <= s.getMinX())
{
return s.getY(0).doubleValue();
}
if (x >= s.getMaxX())
{
return s.getY(s.getItemCount()-1).doubleValue();
}
List<?> items = s.getItems();
for (int i=0; i<items.size()-1; i++)
{
XYDataItem i0 = (XYDataItem) items.get(i);
XYDataItem i1 = (XYDataItem) items.get(i+1);
double x0 = i0.getXValue();
double y0 = i0.getYValue();
double x1 = i1.getXValue();
double y1 = i1.getYValue();
if (x >= x0 && x <= x1)
{
double d = x - x0;
double a = d / (x1-x0);
double y = y0 + a * (y1 - y0);
return y;
}
}
// Should never happen
return 0;
}
}
(此实现钳位在极限。这意味着对于小于最小x值或大于最大x值的x值,最小值的y值/最大x值将分别返回)