DMelt:Plots/4 Showing 2D Shapes
Simple 2D shapes
In addition to data, histograms, functions, jhplot.HPlot canvas can show arbitrary shapes (boxes, text, images, arrows) in the user ("USER") coordinates (i.e. given by the axis values) or in the absolute coordinates ("NDC"). You can mix data and shapes in arbitrary order.
The following shapes can be plotted:
- jhplot.shapes.Arrow - Arrow
- jhplot.shapes.Circle - Circle
- jhplot.shapes.Ellipse - Ellipse
- jhplot.shapes.Line - Line
- jhplot.shapes.Picture - Picture (in PNG or JPG formats)
- jhplot.shapes.Rectan - Rectangle
- jhplot.shapes.Text - Simple (not interactive) text
You should also remember that you can always draw shapes with data points. Here is an example how to draw an ellipse
with semi-major (longest radius) and semi-minor (shortest radius) radii:
Here is a simple code to do this:
from java.awt import * from jhplot import * from jhplot.shapes import * from math import * c1 =HPlot("Canvas",600,600) c1.setGTitle("Drawing shapes") c1.setAntiAlias(1) c1.setNameX("X") c1.setNameY("Y") c1.setRange(-5.0, 5.0, -5, 5.0) c1.visible(1) p1=P1D("Ellipse data") # a, b are the radius on the x and y axes respectively a=3 # major b=2 # minor xshift=1 # (X,Y) position yshift=2 step=0.05 # step ra=[v*step for v in range(0,int(2*3.2/step))] # generate points (3.2 instead of 2*pi!) to close the object for t in ra: x = a*cos(t)+xshift y = b*sin(t)+yshift p1.add(x, y) c1.draw(p1) # export to some image (png,eps,pdf,jpeg...) # c1.export(Editor.DocMasterName()+".png");
You can convert it to Groovy or Java code using the same logic. Decrease the step size to obtain a smooth line.
Now let us construct rotated ellipse by some angle and overlay it with a 2D Ellipse using "2D" shape approach:
The code to generate this image is below:
from java.awt import * from jhplot import * from jhplot.shapes import * from java.util import Random from math import * c1 =HPlot("Canvas",500,500) c1.setGTitle("Rotated ellipse by 45 degress") c1.setAntiAlias(1) c1.setLegend(0) c1.setNameX("X") c1.setNameY("Y") c1.setRange(-10.0, 10.0, -10, 10.0) c1.visible(1) p1=P1D("rotated ellipse") # a, b are the radius on the x and y axes respectively a=4 # semi-major size b=2 # semi-minor size xshift=0 # X,Y positions yshift=0 theta=3.14/4 # rotated by 45 degress (in rad) step=0.1 # steps to plot ra=[v*step for v in range(0,int(6.28/step))] for t in ra: x= a*cos(t)*cos(theta) - b*sin(t)*sin(theta)+xshift y = b*cos(theta)*sin(t) + a*sin(theta)*cos(t)+yshift p1.add(x, y) # filled eclipse ele1= Ellipse(xshift, yshift, a, b) ele1.setFill(1) ele1.setRotation(theta) ele1.setColor(Color.green) ele1.setTransparency(0.5) c1.add(ele1) # set HLabel in the USER coordinate system lab=HLabel("Rotated ellipse", 1, 8) c1.add(lab) # now show all objects c1.draw(p1) # export to some image (png,eps,pdf,jpeg...) # c1.export(Editor.DocMasterName()+".png");
Finally, one can generate random data points following the ellipse shape. We will use parametric description of the ellipse, rotate it and generate random numbers:
The Python code this image is below:
from java.awt import * from jhplot import * from jhplot.shapes import * from java.util import Random from math import * c1 =HPlot("Canvas",500,500) c1.setGTitle("Random ellipse") c1.setAntiAlias(1) c1.setLegend(0) c1.setNameX("X") c1.setNameY("Y") c1.setRange(-10.0, 10.0, -10, 10.0) c1.visible(1) p1=P1D("Random ellipse") rand = Random() # a, b are the radius on the x and y axes respectively a=4 # semi-major axis b=2 # semi-minor exis xshift=0 # (X,Y) position yshift=-1 theta=1.0 # rotation step=0.05 ra=[v*step for v in range(0,int(6.28/step))] for t in ra: # fill random ellipse. x= a*cos(t)*cos(theta) - b*sin(t)*sin(theta)+xshift y = b*cos(theta)*sin(t) + a*sin(theta)*cos(t)+yshift p1.add(x+0.4*rand.nextGaussian(), y+0.5*rand.nextGaussian()) ele1= Ellipse(xshift, yshift, a, b) ele1.setFill(0) ele1.setRotation(theta) ele1.setColor(Color.red) ele1.setTransparency(0.6) c1.add(ele1) # set HLabel in the USER coordinate system lab=HLabel("Random ellipse", 1, 8) c1.add(lab) # now show all objects c1.draw(p1) # export to some image (png,eps,pdf,jpeg...) # c1.export(Editor.DocMasterName()+".png");
You can use the basic 2D primitives to draw shapes. Here is a simple example how to draw such shapes:
You can find a script that generates this image below. It shows how to add X-Y data, histograms a then draw simple 2D graphic primitives on the top:
code 30155238.py
Always use "add" method to add the shape to the canvas. When you draw data, (calling "draw()" method), this will update
the canvas. Or, you can use "c1.update()" method to trigger the update.
In the above example, we use "USER" coordinates. If you want to plot a shape in coordinate system independent of the axis, use "NDC" coordinates (values run from 0 to 1).
Please look at the package jhplot.shapes.HShape that is used to build such shapes.