Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

OpenGL based 2D Plotting Library for Java using AWT and LWJGL

License

NotificationsYou must be signed in to change notification settings

hageldave/JPlotter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenGL based 2D Plotting Library for Java using AWT/Swing andLWJGL throughlwjgl3-awt.An AWTGraphics2D fallback solution was introduced to support systems lacking OpenGL-3.3 as well as MacOS.

Build StatusMaven Central

JPlotter's concept is pretty straight forward, you get aJPlotterCanvas that is backed by OpenGL (or not in case of fallback).What is displayed by this canvas depends on the setRenderer.Most likely you want to set aCoordSysRenderer that displays a coordinate system.Within that coordinate system you may want to display points or lines, which you can do by again using aRenderer (or multiple) as content.APointsRenderer can be used to draw points as in a scatter plot, or aLinesRenderer can be used to make a line chart or contour plot.

JPlotter is also capable of exporting plots as Scalable Vector Graphics (SVG) throughApache Batikas well as exporting to portable document format (PDF) throughApache PDFBox.

More details and information can be found in theWiki.

Maven

JPlotter is available as Maven artifact at the Central Maven Repository.

<dependency>  <groupId>com.github.hageldave.jplotter</groupId>  <artifactId>jplotter</artifactId>  <version>1.0.4</version></dependency>

Teaser Image

See theGallery for more images.

teaser img

Code Example

Before visualizing anything, some data has to be generated first.Lets sample the sine function so we can later plot a line.

DoubleUnaryOperatorfx =Math::sin;intnumCurveSamples =100;double[]curveX =newdouble[numCurveSamples];double[]curveY =newdouble[numCurveSamples];for(inti=0;i<numCurveSamples;i++){doublex =i*Math.PI*2/numCurveSamples;doubley =fx.applyAsDouble(x);curveX[i]=x;curveY[i]=y;}

Lets also mix in some random samples for plotting points.

intnumPointSamples =400;double[]pointsX =newdouble[numPointSamples];double[]pointsY =newdouble[numPointSamples];double[]diffToCurve =newdouble[numPointSamples];for(inti=0;i<numPointSamples;i++){doublex =Math.random()*Math.PI*2;doubley =Math.random()*Math.PI*2-Math.PI;diffToCurve[i] =y-fx.applyAsDouble(x);pointsX[i]=x;pointsY[i]=y;}

Now that data is set up, we are good to go and can think about representation of the data.The sine samples should be visualized as a line, whereas the random samples should be displayed as points.Lets also divide the points into 3 classes:

  1. y(x) < sin(x)-0.5
  2. sin(x)-0.5 <= y(x) <= sin(x)+0.5
  3. sin(x)+0.5 < y(x)
LinessineLine =newLines();intsineColor =0xff66c2a5;sineLine.setGlobalThicknessMultiplier(2)   .setStrokePattern(0xf790)   .addLineStrip(curveX,curveY)   .forEach(segment ->segment.setColor(sineColor));PointspointsC1 =newPoints(DefaultGlyph.CROSS);PointspointsC2 =newPoints(DefaultGlyph.CIRCLE);PointspointsC3 =newPoints(DefaultGlyph.CROSS);intc1Color =0xff8da0cb,c2Color =sineColor,c3Color =0xfffc8d62;for(inti=0;i<numPointSamples;i++){if(diffToCurve[i] < -0.5){pointsC1.addPoint(pointsX[i],pointsY[i]).setColor(c1Color);   }elseif(diffToCurve[i] >0.5) {pointsC3.addPoint(pointsX[i],pointsY[i]).setColor(c3Color);   }else {pointsC2.addPoint(pointsX[i],pointsY[i]).setColor(c2Color);   }}

Alright next we put everything into a coordinate system.

CoordSysRenderercoordsys =newCoordSysRenderer();CompleteRenderercontent =newCompleteRenderer();coordsys.setContent(content      .addItemToRender(sineLine)      .addItemToRender(pointsC1)      .addItemToRender(pointsC2)      .addItemToRender(pointsC3));// lets set the coordinate view to cover the whole sampling spacecoordsys.setCoordinateView(-.5, -3.3,6.5,3.3);

We can also add a legend to the plot so that a viewer can make more sense of the viz.

Legendlegend =newLegend();coordsys.setLegendRightWidth(80);coordsys.setLegendRight(legend      .addLineLabel(2,sineColor,"f(x)")      .addGlyphLabel(DefaultGlyph.CROSS,c1Color,"< f(x)-0.5")      .addGlyphLabel(DefaultGlyph.CIRCLE,c2Color,"~ f(x)")      .addGlyphLabel(DefaultGlyph.CROSS,c3Color,"> f(x)+0.5"));

We will use a blank canvas to display our coordinate system.For exploring the plot we can add some controls for zooming.

booleanuseOpenGL =true;JPlotterCanvascanvas =useOpenGL ?newBlankCanvas() :newBlankCanvasFallback();canvas.setRenderer(coordsys);// lets add some controls for exploring the datanewCoordSysScrollZoom(canvas,coordsys).setZoomFactor(1.7).register();newCoordSysViewSelector(canvas,coordsys) {   {extModifierMask=0;/* no need for shift to be pressed */}publicvoidareaSelected(doubleminX,doubleminY,doublemaxX,doublemaxY) {coordsys.setCoordinateView(minX,minY,maxX,maxY);   }}.register();

Nice, now we conclude with some typical AWT/Swing code to launch the viz in a JFrame.

JFrameframe =newJFrame("Example Viz");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.getContentPane().add(canvas.asComponent());canvas.asComponent().setPreferredSize(newDimension(480,400));canvas.asComponent().setBackground(Color.white);// register a listener that will cleanup GL resources on window closingcanvas.addCleanupOnWindowClosingListener(frame);SwingUtilities.invokeLater(()->{frame.pack();frame.setVisible(true);});

We can also add a pop up menu for exporting to SVG, PDF or PNG.

PopupMenumenu =newPopupMenu();canvas.asComponent().add(menu);canvas.asComponent().addMouseListener(newMouseAdapter() {publicvoidmouseClicked(MouseEvente) {if(SwingUtilities.isRightMouseButton(e))menu.show(canvas.asComponent(),e.getX(),e.getY());   }});// Exporting SVGMenuItemsvgExport =newMenuItem("SVG export");svgExport.addActionListener(e->{Documentsvg =SVGUtils.containerToSVG(frame.getContentPane());SVGUtils.documentToXMLFile(svg,newFile("example_export.svg"));System.out.println("exported SVG.");});menu.add(svgExport);// Exporting PDFMenuItempdfExport =newMenuItem("PDF export");pdfExport.addActionListener(e->{PDDocumentdoc =PDFUtils.containerToPDF(frame.getContentPane());doc.save("example_export.pdf");doc.close();});menu.add(pdfExport);// Exporting PNGMenuItempngExport =newMenuItem("PNG export");pngExport.addActionListener(e->{Imgimg =newImg(frame.getContentPane().getSize());img.paint(g ->frame.getContentPane().paintAll(g));ImageSaver.saveImage(img.getRemoteBufferedImage(),"example_export.png");System.out.println("exported PNG.");});menu.add(pngExport);

Example Viz

Source


[8]ページ先頭

©2009-2025 Movatter.jp