我有大量数据,我希望绘制在范围从 10k 点到大约 2000 万点的图表上。在 10k 点处,情节以正常的速度(在一秒内)发生,但在 2000 万点处,情节似乎需要几分钟。
我正在为程序使用 Java 并用另一种语言重写代码,只是为了提高仅在最大数据集时出现的单个图的图形绘制速度不在卡片中。
这个速度是我必须忍受的,因为 2000 万点图由于数据大小而固有地需要这么长时间,还是我错过了一些优化标志/方法/等?
我的数据位于 13,000 x 4096 的二维数组中,称为数据。这是从 Main.java 中的绘图函数外部填充的
//In Plot.java
public class PlotG extends JPanel
{
double xscale = 0.0;
double yscale = 0.0;
protected void paintComponent(Graphics g)
{
super.paintCompnent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHint.Key_ANTIALIASING, RenderingHint.VALUE_ANTIALIAS_ON);
//Scaling
int sizew = Data.size();
int sizeh = Data.get(0).size();
xscale = (getWidth()*1.0)/(sizew *1.0);
yscale = (getHeight()*1.0)/(sizeh *1.0);
//Set Colour
g2.setPaint(Color.GREEN);
//Plot
for(int j=0; j<sizew; j++)
{
for(int k=0;k<sizeh; k++)
{
if(Data.get(j).get(k) > MinimumValueToPlot) //I only plot points above the constant value MinimumValueToPlot
{
int x = xscale*j;
int y = yscale*k;
g2.fillOval(x,y,1,1);
}
}
}
return;
}
}
private Plot dataPlot = new Plot()
public PlotStuff(ArrayList<ArrayList<Double>> In)
{
Data = In;
InitPLot(getContentPane());
}
private void InitPlot(Container contentPane)
{
getContentPane().setBackground(Color.GRAY);
getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
setMinimumSize(new Dimension(1650, 830));
pack();
GraphPanel = new JPanel();
GraphPanel.setBounds(6,11,1470,750);
GraphPanel.setBorder( BorderFactory.createTitleBorder( BorderFactory.createLineBorder(Color.GREEN, 2),
"Title",
TitledBorder.DEFAULT_JUSTIFICATION,
TitledBorder.DEFAULT_POSITION,
new Font("Tahoma", Font.BOLD, 18),
Color.WHITE));
getContentPanel().add(GraphPanel);
GraphPanel.setLayout(new BorderLayout());
dataPlot.setBackGround(Color.BLUE);
dataPlot.setForeGround(Color.WHITE);
dataPlot.setPreferredSize(new Dimension(1470, 750));
GraphPanel.add(dataPlot);
return;
}
//in Main.java
.
.
PlotStuff p = new PlotStuff(Data);
p.redrawGraph();
p.setVisible();
.
.
如果高于我的常量MinimumValueToPlot的点数达到 2000 万及以上,是否有办法提高速度?鉴于我的最大可能的数据集13K X 4096 = 53248000,这是可能的,但分以上的最高经验的数量MinimumValueToPlot是迄今为止只有20万元。
我在 JPanel 声明中做错了什么吗?我看到一些讨论说不应该使用setPreferredSize?是这种情况吗?
谢谢。
Data
是一个二维数组,但它不是。这是一个ArrayList
的ArrayLists
。改为使用实际数组。而不是ArrayList<ArrayList<Double>>
你会做double[][]
。
fillOval
以设置单个像素的颜色。这会导致巨大的不必要的开销。您基本上是在告诉您的应用程序计算大小为 1x1 的椭圆形的像素 2000 万次!建议你创建一个BufferedImage,获取它的像素数组,直接设置像素值。然后,完成后,将该图像绘制到 Graphics2d 对象:
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D imgGraphics2D = img.createGraphics();
imgGraphics2D.setColor(Color.white);
imgGraphics2D.fillRect(0, 0, getWidth(), getHeight());
imgGraphics2D.dispose();
byte[] pixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();
for(int j=0; j < sizew; j++)
{
for(int k=0; k < sizeh; k++)
{
if(data[j][k] > minimumValueToPlot)
{
int x = (int)(xscale * j);
int y = (int)(yscale * k);
int pixelindex = (y * getWidth() + x) * 3;
pixels[pixelindex + 1] = 255; // set the green byte
}
}
}
g2.setComposite(AlphaComposite.Src);
g2.drawImage(img, 0, 0, null);
请记住这一点,因为我是凭记忆写的。
(我也冒昧重命名的Data
,以data
和MinimumValueToPlot
到minimumValueToPlot
。在Java中按照惯例变量以小写字母从阶级区分它们开始。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句