DMelt:Plots/2 Plots in 2D

From HandWiki
Revision as of 07:58, 4 April 2023 by MainEditor (talk | contribs) (→‎Other charts)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Member


Plots in 2D

There are several canvases to show data in 2D: jhplot.Plot jhplot.Plot, jhplot.HPlot jhplot.HPlot,jhplot.HPlotJa jhplot.HPlotJa, jhplot.SPlot jhplot.SPlot, jhplot.HPlotXY jhplot.HPlotXY and many other pads.

Plots using MatLab syntax

jhplot.Plot jhplot.Plot is a simplest canvas to show data and functions. It is less Java oriented, but more oriented towards MatLab syntax (which does not assume operation with objects and dynamical access of methods).

from jhplot  import *

j=Plot()
j.plot([-1,2,3], [0.5, 0.2, 0.3])
j.show()
j.export("a.pdf")   # save as PDF file 
# j.export("a.eps") # save as EPS (PostScript) format
# j.export("a.svg") # save as SVG file

Here we created X-Y plot and saved as PDF image. You can also use the "savefig()" method, which is equivalent to the export method.

Interactive 2D canvases

Below we discuss more complicated plot canvases which can be used to display data in 2D. Such canvases usually have the names starting with the capital "H". Typically, you can build a plot to show 2D data as this:


from jhplot *
c1 = HPlot("Canvas",600,400,2,1) # canvas size 600x400, 2 plot regions
c1.visible(100,200)  # make it visible and position at 100 , 200 pixels on the screen
c1.setAutoRange()    # autorange for X
c1.draw(object1)     # draw object1 (H1D,F1D,P1D etc)
c1.draw(object2)     # draw a new object
c1.export("figure.pdf") # export to PDF file

This code create a canvas with the size 600x400 (in pixels), it has 2 pads to show data. The method visible(100,200) make the canvas visible and sets its location on the screen at position 100 (in X from left conner) and 200 (from top) in pixels. If you want a default position, jut call "visible()". Then you can draw any mathematical object or data. Then you can export the image to vector format. Now you are ready to plot functions, histograms and datasets. See the jhplot.HPlot jhplot.HPlot documentation. It should be noted the jhplot.HPlot jhplot.HPlot canvas can be replaced by any other canvas described above.


Several plotting regions

These canvases can be used to show several pads (plot regions) with plotted objects. Specify the number of divisions in X and Y in the constructors. The navigate to a specific plot region using the method "cd()". Here is example of how to create 2x2 pads on a single canvas:

from jhplot  import *

c1 = HPlot("Canvas",500,400,2,2)
c1.visible()
c1. setRangeAll(0,10,0,10)
h1 = P1D("Simple")

c1.cd(1,1)
h1.add(5,6);  c1.draw(h1)

c1.cd(1,2)
h1.add(4,3); c1.draw(h1)

c1.cd(2,1)
h1.add(3,3); c1.draw(h1)

c1.cd(2,2)
h1.add(2,1); c1.draw(h1)
c1.export ("example.pdf") # export to PDF

DMelt example: Shwoing X-Y data on 4 canvas regions

This works for jhplot.HPlot jhplot.HPlot, jhplot.HPlotJa jhplot.HPlotJa, jhplot.HPlot3D jhplot.HPlot3D and many other pads.

Here we use the same X and Y ranges. One can use "setAutoRange()" (after each "cd()") method to set autorange for each pad. Also, try "setRange(xmin,xmax,ymin,ymax)" to set fixed ranges for each pads. it shows 4 pads with data points.

The plots are fully customizable, i.e. one can change any attribute (axis, label, ticks, ticks label).

Exporting to images

When DMelt functions, histograms, data structures are shown, one can create an image using the menu [File]-[Export]. One can also save image in a file using the method "export(file)" to a variety of vector graphics formats as well as bitmap image formats.

In the example below, we save an instance of the HPlot class to a PDF file:

c1.export('image.pdf')

we export drawings on the canvas HPlot (c1 represents its instance) into a PDF file. One can also export it into PNG, JPEG, EPS, PS etc. formats using the appropriate extension for the output file name.

As example, simply append the statement "c1.export('image.ps')" at the end of code, and your image will be saved to a PostScript file "image.ps".

Images can be generated in a background (without a pop-up frame with the canvas). For this, use the method "c1.visible(0)", where "0" means Java false.

Axis labels

Can be set using setNameX("label") and setNameY("label"). These are global methods which should be applied to the HPlot canvas. However, every plotting object have their own methods, such as "setLabelX("label")" and setLabelY("label")". If the labels are set to the object, the plot will display the object labels rather than those set using setNameX() and setNameY().


Ticks and subticks

One can redefine ticks using several methods of the jhplot.HPlot jhplot.HPlot

setRange(0,10,0,10)    # set range for X and Y 
  setNumberOfTics(1)     # redefine ticks   
  setNumberOfTics(0,2)   # set 2 ticks on X
  setNumberOfTics(1,5)   # set 5 ticks on Y
  setSubTicNumber(0,2)   # set 2 subticks on X
  setSubTicNumber(1,4)   # set 4 subticks on Y

The simple example illustrates this:


from jhplot  import *

c1 = HPlot("Canvas")
c1.visible()
c1.setRange(0,10,0,10)
c1.setNumberOfTics(0,2) 
c1.setNumberOfTics(1,5)
c1.setSubTicNumber(0,2)
c1.setSubTicNumber(1,4)

h1 = P1D("Simple1")
xpos=5
ypos=7
h1.add(xpos,ypos)
c1.draw(h1)

lab=HLabel("Point", xpos, ypos, "USER")
c1.add(lab)
c1.update()
c1.export ("example.pdf")


We labeled a point and generated a PDF files with the figure as shown in this figure:

DMelt example: Show ticks and custom labels with annotations

Showing shapes and objects

You can show data and functions together with different 2D objects. Here is a simple example that shows a histogram, a data set in X-Y and 3 ellipses:

from java.awt import Font,BasicStroke,Color
from java.util import Random
from jhplot import HLabel, HPlot 
from jhplot.shapes  import *

# make empty canvas in some range
c1 =HPlot("Canvas",600,400)
c1.setGTitle("HShape package to draw Java 2D objects")
c1.setLegend(0)
c1.setNameX("X")
c1.setNameY("Y")
c1.setRange(-4.0, 4.0, 0.0, 20.0)
c1.visible(1)

# show a line in the NDC system
line = Line(0.1,0.9, 0.2, 0.9)
line.setPosCoord("NDC")
line.setColor(Color.red)
line.setTransparency(0.5)
c1.add(line)

#show a line in the NDC system
line = Line(0.1,0.85, 0.2, 0.85);
line.setDashed(3.0);
line.setPosCoord("NDC");
line.setColor(Color.blue);
line.setTransparency(0.5);
c1.add(line);

# show dotted line in the USER system
line = Line(-2.0, 10, -1.0, 12.0)
line.setDotted(2.0)
line.setColor(Color.magenta)
line.setTransparency(0.5)
c1.add(line)


# arrow
arr = Arrow(-2, 2, -2, 10)
c1.add(arr)

# arrow in the NDC system
arr = Arrow(0.85, 0.5, 0.85, 0.7)
arr.setColor(Color.blue)
arr.setPosCoord("NDC")
stroke = BasicStroke(5.0)
arr.setStroke(stroke)
arr.setType(2)
c1.add(arr)

# arrow in the NDC system
arr = Arrow(-2.0, 4.6, -2.5, 8.0)
arr.setColor(Color.black)
stroke = BasicStroke(1.0)
arr.setStroke(stroke)
arr.setType(3)
c1.add(arr)


# arrow in the NDC system
arr = Arrow(-3.0, 2.6, -2.0, 10.7)
arr.setColor(Color.black)
stroke = BasicStroke(1.0)
arr.setStroke(stroke)
arr.setType(1)
c1.add(arr)




tex=  Text("This is a text",-2.4, 12)
c1.add(tex)


cic= Circle(-0.5, 10, 2.0)
cic.setFill(1)
cic.setColor(Color.red)
cic.setTransparency(0.5)
c1.add(cic)


# filled eclipse
ele= Ellipse(-1.2, 8, 1.0, 0.9)
ele.setFill(1)
ele.setColor(Color.green)
ele.setTransparency(0.8)
c1.add(ele)


# show circle
cic=Circle(-0.9, 11, 1.5)
cic.setFill(0)
c1.add(cic)


# rectangle
rec=Rectan(0.0, 10.0, 0.9, 1.2);
rec.setFill(1);
c1.add(rec);


rec= Rectan(2.0, 3.0, 2.9, 1.6);
rec.setFill(1);
rec.setColor(Color.yellow);
rec.setTransparency(0.7);
c1.add(rec);


# set HLabel in the USER coordinate system
lab=HLabel("HLabel in USER", -2, 10);
c1.add(lab);


# set HLabel in the normilised coordinate system
lab=HLabel("HLabel in NDC", 0.5, 0.2, "NDC");
c1.add(lab);

# now show all objects
c1.update();



# export to some image (png,eps,pdf,jpeg...)
# c1.export(Editor.DocMasterName()+".png");

Here is the output of this example:

DMelt example: Show basic shapes (Line, Circle, image)

Post editing

jhplot.HPlotJa jhplot.HPlotJa can be used to edit figures. For example, one can make inserts if one creates 2 plotting pads and then one can edit the pads using the "mouse-click" fashion. For example, run this script:

from java.awt import Color,Font
from java.util import Random
from jhplot  import P1D
from jhplot  import HPlotJa
 
c1 = HPlotJa("Canvas",800,600,2,1)
c1.visible()
c1.setAutoRange()

x=10
y=20
xLeft=2
xRight=2
yLower=3
yUpper=3
xLeftSys=5
xRightSys=3
yUpperSys=3
xLowerSys=3

p1=P1D("TEST")
p1.add(x,y,xLeft,xRight,yUpper,yLower,xLeftSys,xRightSys,yUpperSys,xLowerSys);
p1.setErrTicSize(20)
p1.setPenWidthErrSys(2)
p1.setPenWidthErr(4)
p1.setStyle("p")
p1.setErr(1)
p1.setErrSys(1)
p1.setColor(Color.black)
p1.setSymbolSize(7)
c1.draw(p1)
c1.update()

# export to some image (png,eps,pdf,jpeg...)
# c1.export(Editor.DocMasterName()+".png")


Then edit the figure (increase the size of one pad, and then drag the other one):

DMelt example: HPlotJa shows data points with errors


Similarly, one can achieve the same using the method "setPad()" where you can specify the location and the sizes of the plot regions The script below creates 2 plotting pads. The second pad is located inside the first one. Then you can plot data as usual, navigating to certain pads using the "cd(i,j)" method.

from jhplot  import  *
c1 = HPlotJa("Canvas",600,400,2,1)
c1.visible(1)

# change pad positions and sizes
c1.setPad(1,1,0.1, 0.1, 0.8,0.8)
c1.setPad(2,1,0.5, 0.14, 0.3,0.3)

Interactive plotting

jhplot.HPlotJas jhplot.HPlotJas canvas represents a way to prepare all objects for plotting, fitting and rebinning of data.

Polar coordinates

For the polar coordinates, use the jhplot.HChart jhplot.HChart canvas. A small code below shows ho to show a dataset filled from the X-Y array jhplot.P1D jhplot.P1D

from java.awt import Color
from java.awt import Font
from java.util import Random
from math  import *
from jhplot import HChart,P1D

c1 = HChart("Canvas",600,500, 2, 1)
c1.setGTitle("Polar coordinates")
c1.visible()

c1.cd(1,1)
c1.setName("Polar coordinates-I")
c1.setChartPolar()
p1= P1D("test 1")
p2= P1D("test 2")
# fill
rand = Random() 
for i in range(20):
      x=4.0*i # x-value
      p1.add(i*4, 10.0*rand.nextGaussian());
      p2.add(i*2, 5.0*rand.nextGaussian());
c1.add(p1)
#c1.add(p2)
c1.update()

c1.cd(2,1)
p3= P1D("Example")
for i in range(0,3*360,5):
    p3.add( 90-i,i)
c1.setChartPolar()
c1.setName("Polar coordinates-II")
c1.add(p3)
c1.update()

# export to some image (png,eps,pdf,jpeg...)
# c1.export(Editor.DocMasterName()+".png")

DMelt example: Charts using polar coordinates


Example with 2D plot regions

In the example below, we create 4 plot regions (2 by 2) and plot functions and a histogram (see DMelt:DataAnalysis/3_Histograms). Then we export the plot to EPS file for inclusion to a LaTeX document

from java.util import Random
from jhplot import F2D,H2D,HPlot3D

c1  = HPlot3D("Canvas",600,400,2,1)
c1.visible(1)
c1.setGTitle("HPlot3D canvas tests")
rand =Random()

h1=H2D("Test1",30,-4.5, 4.5, 30, -4.0, 4.0)
for i in range(1000):
       h1.fill(rand.nextGaussian(),0.5*rand.nextGaussian())

c1.cd(1,1)
c1.setBars()
c1.draw(h1)
c1.setScaling(8)
c1.setRotationAngle(10)
c1.update()

c1.cd(2,1)
c1.setSurface()
c1.draw(h1)


The output of this script is shown below:

DMelt example: Show 2D (H2D) histogram in 3D using bar style and surface style

Use setAutoRange() if you want X-Y-Z ranges taken from the function definitions. Otherwise, use "setRange()" to fix ranges. Here is another example showing 2D plots with data:

from jhplot  import *
from java.util import Random
from java.awt import Color

c1 = HPlot3D("Canvas",500,500)
c1.setGTitle("Interactive 3D galaxy") 
c1.setRange(-10,10,-10,10,-10,10)
c1.setNameX("X")
c1.setNameY("Y")
c1.visible(1)


# create P2D objects in 3D 
p1= P2D("Galaxy")
p1.setSymbolSize(2);
p1.setSymbolColor(Color.blue);

rand = Random()
for i in range(5000):
      x=3*rand.nextGaussian()
      y=3*rand.nextGaussian()
      z=0.4*rand.nextGaussian()
      p1.add(x,y,z)
c1.draw(p1)

h2=P2D("Core")
h2.setSymbolSize(2) 
h2.setSymbolColor(Color.yellow)
for i in range(5000):
      x=0.9*rand.nextGaussian()
      y=0.9*rand.nextGaussian()
      z=0.8*rand.nextGaussian()
      h2.add(x,y,z)
c1.draw(h2)

The output is shown below:

DMelt example: Show a galaxy in 3D

Embedding in JFrame

It is possible to embed DataMelt canvases in Java java.swing.JFrame java.swing.JFrame, so you can build an application with custom buttons. Here is an example:

from jhplot import *
c1=HPlot("GUI")
fr=c1.getFrame()
# .. fill c1 frame with data (H1D,P1D)
# do what you like to do, i.e. add any component
# then 
fr.pack()

Using GROOT

DMelt includes GROOT package developed at JLab. Its syntax reminds the PyROOT environment. You can find example in Jython and Java here:


Density plots

You can also make density plots in which color represent density (or values). Look at this rather comprehensive example which shows how to plot F2D functions or 2D histograms (H2D) using several pads:

from java.awt import Color
from jhplot import *

c1 = HPlot3D('Canvas',600,600)
c1.setNameX('X')
c1.setNameY('Y')
c1.setContour()
c1.visible()
c1.setAutoRange()
f1=F2D('(0.5*x)^2+y^2', -2.0, 2.0, -2.0, 2.0)
c1.draw(f1)

DMelt example: Function using a HPlot3D canvas with a contour style


Waterloo scientific charts

DataMelt allows to access reach Waterloo scientific graphics package implemented in Java. The original web page is [1]. However, DataMelt only used the base of the Waterloo package. A support for Groovy and Jython is done via the internal DataMelt api.

The API of these Java libraries for scientific plotting can be found Waterloo graphics package Waterloo graphics package. Let us give a small example of X-Y plot:

# This example shows how to plot X-Y using Waterloo scientific library 

from kcl.waterloo.swing import GCFrame
from kcl.waterloo.graphics import GJGraph,GJGraphContainer
from kcl.waterloo.graphics.plots2D import GJScatter,GJPlotInterface

f=GCFrame("Scatter plot")
gc=GJGraphContainer.createInstance(GJGraph.createInstance())
f.add(gc)

x=[]
y=[]
for i in range(-100,100,5):
      x.append(i)
      y.append(i*i)

p=GJScatter.createInstance()
p.setXData(x)
p.setYData(y)

gc.getView().add(p)
gc.getView().autoScale()

print "Creating SVG image.."
from kcl.waterloo.export import ExportFactory
from java.io import File
ExportFactory.saveAsSVG(gc, File("canvas2D_points_waterloo.svg"))

This plot shows the function x*x as shown below:

DMelt example: Plotting X-Y using Waterloo scientific library


XChart scientific charts

DataMelt supports XChart library [1] and optimizes it for Jython and Groovy. You can find the API [API]

Let us give a small Jython example of a X-Y plot:

from org.knowm.xchart import BitmapEncoder;
from org.knowm.xchart.BitmapEncoder import BitmapFormat;
from org.knowm.xchart import VectorGraphicsEncoder;
from org.knowm.xchart.VectorGraphicsEncoder import VectorGraphicsFormat;
from org.knowm.xchart import XYChart;
from org.knowm.xchart import XYSeries;
from org.knowm.xchart.style.markers import SeriesMarkers;

# Creates a simple Chart and saves it as a PNG and JPEG image file. */
xData = [0.0, 1.0, 2.0,  3.0, 4.0]
yData = [2.0, 1.0, 0.0, -2.0, -3.0]

# Create Chart
chart = XYChart(500, 400);
chart.setTitle("Sample Chart");
chart.setXAxisTitle("X");
chart.setXAxisTitle("Y");
series = chart.addSeries("y(x)", xData, yData);
series.setMarker(SeriesMarkers.CIRCLE);

# saving options
# BitmapEncoder.saveBitmap(chart, "./Sample_Chart", BitmapFormat.PNG);
# BitmapEncoder.saveBitmap(chart, "./Sample_Chart", BitmapFormat.JPG);
# BitmapEncoder.saveJPGWithQuality(chart, "./Sample_Chart_With_Quality.jpg", 0.95f);
# BitmapEncoder.saveBitmap(chart, "./Sample_Chart", BitmapFormat.BMP);
# BitmapEncoder.saveBitmap(chart, "./Sample_Chart", BitmapFormat.GIF);

# BitmapEncoder.saveBitmapWithDPI(chart, "./Sample_Chart_300_DPI", BitmapFormat.PNG, 300);
# BitmapEncoder.saveBitmapWithDPI(chart, "./Sample_Chart_300_DPI", BitmapFormat.JPG, 300);
# BitmapEncoder.saveBitmapWithDPI(chart, "./Sample_Chart_300_DPI", BitmapFormat.GIF, 300);

#VectorGraphicsEncoder.saveVectorGraphic(chart, "./Sample_Chart", VectorGraphicsFormat.EPS);
VectorGraphicsEncoder.saveVectorGraphic(chart, "./Sample_Chart", VectorGraphicsFormat.PDF);
#VectorGraphicsEncoder.saveVectorGraphic(chart, "./Sample_Chart", VectorGraphicsFormat.SVG);
print("Image saved: Sample_Chart.pdf")

This plot creates high-quality image like this:

DMelt example: Show 2D chart using XChart with output to PDF and SVG

The XChart library can create the following plots:

  • Line charts
  • Scatter charts
  • Area charts
  • Bar charts
  • Histogram charts
  • Pie charts
  • Donut charts
  • Bubble charts
  • Stick charts
  • Dial charts
  • Radar charts
  • OHLC charts
  • Box charts
  • Heat maps
  • Error bars
  • Logarithmic axes
  • Number, Date and Category X-Axis
  • Multiple series
  • User-defined axes range
  • Definable legend placement

All images can be created in PDF, PNG, JPG, BMP and GIF. The possibility of CSV import and export is also included.

Other charts

DataMelt can be used to plot many other types of charts, such as Candlestick chart. You can also create fully customizable layouts for 2D charts.

References

  1. XChart Library [2]