mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
add patches package in plotlib
This commit is contained in:
parent
6ac0f2dbf7
commit
a4a8ba82e8
@ -1493,6 +1493,67 @@ public class GraphicFactory {
|
||||
return new GraphicCollection[]{stemlines, graphics};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a polygon
|
||||
*
|
||||
* @param xa X coordinate array
|
||||
* @param ya Y coordinate array
|
||||
* @param pgb PolygonBreak
|
||||
* @return Graphic
|
||||
*/
|
||||
public static Graphic createPolygon(Array xa, Array ya, PolygonBreak pgb) {
|
||||
double x, y;
|
||||
int n = (int) xa.getSize();
|
||||
PolygonShape pgs;
|
||||
PointD p;
|
||||
List<PointD> points = new ArrayList<>();
|
||||
IndexIterator xIter = xa.getIndexIterator();
|
||||
IndexIterator yIter = ya.getIndexIterator();
|
||||
while (xIter.hasNext()){
|
||||
x = xIter.getDoubleNext();
|
||||
y = yIter.getDoubleNext();
|
||||
p = new PointD(x, y);
|
||||
points.add(p);
|
||||
}
|
||||
if (points.size() > 2) {
|
||||
pgs = new PolygonShape();
|
||||
pgs.setPoints(points);
|
||||
Graphic graphic = new Graphic(pgs, pgb);
|
||||
return graphic;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a polygon
|
||||
*
|
||||
* @param xa X coordinate array
|
||||
* @param ya Y coordinate array
|
||||
* @param pgb PolygonBreak
|
||||
* @return Graphic
|
||||
*/
|
||||
public static Graphic createPolygon(Array xy, PolygonBreak pgb) {
|
||||
double x, y;
|
||||
int n = xy.getShape()[0];
|
||||
PolygonShape pgs;
|
||||
PointD p;
|
||||
List<PointD> points = new ArrayList<>();
|
||||
IndexIterator iter = xy.getIndexIterator();
|
||||
while (iter.hasNext()){
|
||||
x = iter.getDoubleNext();
|
||||
y = iter.getDoubleNext();
|
||||
p = new PointD(x, y);
|
||||
points.add(p);
|
||||
}
|
||||
if (points.size() > 2) {
|
||||
pgs = new PolygonShape();
|
||||
pgs.setPoints(points);
|
||||
Graphic graphic = new Graphic(pgs, pgb);
|
||||
return graphic;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add polygons
|
||||
*
|
||||
|
||||
@ -323,6 +323,12 @@ public class Plot2D extends AbstractPlot2D {
|
||||
case RECTANGLE:
|
||||
this.drawRectangle(g, (RectangleShape) shape, (PolygonBreak) cb, false, area);
|
||||
break;
|
||||
case CIRCLE:
|
||||
this.drawCircle(g, (CircleShape) shape, (PolygonBreak) cb, false, area);
|
||||
break;
|
||||
case ELLIPSE:
|
||||
this.drawEllipse(g, (EllipseShape) shape, (PolygonBreak) cb, false, area);
|
||||
break;
|
||||
case ARC:
|
||||
this.drawArc(g, (ArcShape) shape, (PolygonBreak) cb, area);
|
||||
break;
|
||||
@ -874,6 +880,96 @@ public class Plot2D extends AbstractPlot2D {
|
||||
g.draw(rshape);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawCircle(Graphics2D g, CircleShape rs, PolygonBreak aPGB,
|
||||
boolean isSelected, Rectangle2D area) {
|
||||
Extent extent = rs.getExtent();
|
||||
double[] sXY;
|
||||
sXY = projToScreen(extent.minX, extent.minY + extent.getHeight(), area);
|
||||
double x = sXY[0];
|
||||
double y = sXY[1];
|
||||
double width = this.projXLength(extent.getWidth(), area);
|
||||
java.awt.Shape shape = new Ellipse2D.Double(x, y, width, width);
|
||||
|
||||
if (aPGB.isDrawFill()) {
|
||||
Color aColor = aPGB.getColor();
|
||||
if (isSelected) {
|
||||
aColor = this.getSelectedColor();
|
||||
}
|
||||
if (aPGB.isUsingHatchStyle()) {
|
||||
int size = aPGB.getStyleSize();
|
||||
BufferedImage bi = getHatchImage(aPGB.getStyle(), size, aPGB.getColor(), aPGB.getBackColor());
|
||||
Rectangle2D rect = new Rectangle2D.Double(0, 0, size, size);
|
||||
g.setPaint(new TexturePaint(bi, rect));
|
||||
g.fill(shape);
|
||||
} else {
|
||||
g.setColor(aColor);
|
||||
g.fill(shape);
|
||||
}
|
||||
} else if (isSelected) {
|
||||
g.setColor(this.getSelectedColor());
|
||||
g.fill(shape);
|
||||
}
|
||||
|
||||
if (aPGB.isDrawOutline()) {
|
||||
BasicStroke pen = new BasicStroke(aPGB.getOutlineSize());
|
||||
g.setStroke(pen);
|
||||
g.setColor(aPGB.getOutlineColor());
|
||||
g.draw(shape);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawEllipse(Graphics2D g, EllipseShape rs, PolygonBreak aPGB,
|
||||
boolean isSelected, Rectangle2D area) {
|
||||
Extent extent = rs.getExtent();
|
||||
double[] sXY;
|
||||
sXY = projToScreen(extent.minX, extent.minY + extent.getHeight(), area);
|
||||
double x = sXY[0];
|
||||
double y = sXY[1];
|
||||
double width = this.projXLength(extent.getWidth(), area);
|
||||
double height = this.projYLength(extent.getHeight(), area);
|
||||
java.awt.Shape shape = new Ellipse2D.Double(x, y, width, height);
|
||||
|
||||
AffineTransform atf = g.getTransform();
|
||||
if (rs.getAngle() != 0) {
|
||||
AffineTransform newATF = (AffineTransform) atf.clone();
|
||||
newATF.translate(x + width / 2, y + height / 2);
|
||||
newATF.rotate(Math.toRadians(rs.getAngle()));
|
||||
g.setTransform(newATF);
|
||||
shape = new Ellipse2D.Double(-width * 0.5, -height * 0.5, width, height);
|
||||
}
|
||||
|
||||
if (aPGB.isDrawFill()) {
|
||||
Color aColor = aPGB.getColor();
|
||||
if (isSelected) {
|
||||
aColor = this.getSelectedColor();
|
||||
}
|
||||
if (aPGB.isUsingHatchStyle()) {
|
||||
int size = aPGB.getStyleSize();
|
||||
BufferedImage bi = getHatchImage(aPGB.getStyle(), size, aPGB.getColor(), aPGB.getBackColor());
|
||||
Rectangle2D rect = new Rectangle2D.Double(0, 0, size, size);
|
||||
g.setPaint(new TexturePaint(bi, rect));
|
||||
g.fill(shape);
|
||||
} else {
|
||||
g.setColor(aColor);
|
||||
g.fill(shape);
|
||||
}
|
||||
} else if (isSelected) {
|
||||
g.setColor(this.getSelectedColor());
|
||||
g.fill(shape);
|
||||
}
|
||||
|
||||
if (aPGB.isDrawOutline()) {
|
||||
BasicStroke pen = new BasicStroke(aPGB.getOutlineSize());
|
||||
g.setStroke(pen);
|
||||
g.setColor(aPGB.getOutlineColor());
|
||||
g.draw(shape);
|
||||
}
|
||||
|
||||
if (rs.getAngle() != 0) {
|
||||
g.setTransform(atf);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawArc(Graphics2D g, ArcShape aShape, PolygonBreak aPGB,
|
||||
Rectangle2D area, float dist, float ex, Font labelFont, Color labelColor) {
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
package org.meteoinfo.geo.drawing;
|
||||
|
||||
import org.meteoinfo.common.*;
|
||||
import org.meteoinfo.geometry.geoprocess.GeometryUtil;
|
||||
import org.meteoinfo.geometry.legend.*;
|
||||
import org.meteoinfo.geometry.geoprocess.Spline;
|
||||
import org.meteoinfo.common.colors.ColorUtil;
|
||||
@ -2459,7 +2460,11 @@ public class Draw {
|
||||
drawPolygonShape(pgs, (PolygonBreak) aGraphic.getLegend(), g);
|
||||
break;
|
||||
case RECTANGLE:
|
||||
drawPolygon(points, (PolygonBreak) aGraphic.getLegend(), g);
|
||||
//drawPolygon(points, (PolygonBreak) aGraphic.getLegend(), g);
|
||||
Extent extent = GeometryUtil.getExtent(points);
|
||||
drawRectangle(new PointF((float)extent.minX, (float)extent.minY),
|
||||
(float)extent.getWidth(), (float)extent.getHeight(),
|
||||
(PolygonBreak) aGraphic.getLegend(), g);
|
||||
break;
|
||||
case CURVE_LINE:
|
||||
drawCurveLine(points, (PolylineBreak) aGraphic.getLegend(), g);
|
||||
|
||||
@ -13,6 +13,7 @@ import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.meteoinfo.common.Extent;
|
||||
import org.meteoinfo.common.Extent3D;
|
||||
import org.meteoinfo.common.PointD;
|
||||
import org.meteoinfo.common.PointF;
|
||||
import org.meteoinfo.geometry.shape.*;
|
||||
import org.meteoinfo.ndarray.*;
|
||||
|
||||
@ -142,11 +143,12 @@ public class GeometryUtil {
|
||||
double minz = p.Z;
|
||||
double maxz = p.Z;
|
||||
for (int i = 1; i < points.length; i++) {
|
||||
p = points[i];
|
||||
if (minx > p.X) {
|
||||
minx = p.M;
|
||||
minx = p.X;
|
||||
}
|
||||
if (maxx < p.X) {
|
||||
maxx = p.M;
|
||||
maxx = p.X;
|
||||
}
|
||||
if (miny > p.Y) {
|
||||
miny = p.Y;
|
||||
@ -173,6 +175,43 @@ public class GeometryUtil {
|
||||
return extent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extent of the points
|
||||
*
|
||||
* @param points
|
||||
* @return Extent
|
||||
*/
|
||||
public static Extent getExtent(PointF[] points) {
|
||||
PointF p = points[0];
|
||||
double minx = p.X;
|
||||
double maxx = p.X;
|
||||
double miny = p.Y;
|
||||
double maxy = p.Y;
|
||||
for (int i = 1; i < points.length; i++) {
|
||||
p = points[i];
|
||||
if (minx > p.X) {
|
||||
minx = p.X;
|
||||
}
|
||||
if (maxx < p.X) {
|
||||
maxx = p.X;
|
||||
}
|
||||
if (miny > p.Y) {
|
||||
miny = p.Y;
|
||||
}
|
||||
if (maxy < p.Y) {
|
||||
maxy = p.Y;
|
||||
}
|
||||
}
|
||||
|
||||
Extent extent = new Extent();
|
||||
extent.minX = minx;
|
||||
extent.maxX = maxx;
|
||||
extent.minY = miny;
|
||||
extent.maxY = maxy;
|
||||
|
||||
return extent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ellipse coordinate
|
||||
* @param x0 Center x
|
||||
|
||||
@ -90,7 +90,6 @@ package org.meteoinfo.geometry.graphic;
|
||||
public void setLegend(ColorBreak legend) {
|
||||
_legend = legend;
|
||||
updateResizeAbility();
|
||||
updateResizeAbility();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -42,6 +42,7 @@ package org.meteoinfo.geometry.legend;
|
||||
*/
|
||||
public PolygonBreak() {
|
||||
super();
|
||||
this.color = Color.cyan;
|
||||
this.breakType = BreakTypes.POLYGON_BREAK;
|
||||
outlineColor = Color.black;
|
||||
outlineSize = 1.0f;
|
||||
|
||||
@ -1,73 +1,122 @@
|
||||
/* Copyright 2012 Yaqiang Wang,
|
||||
* yaqiang.wang@gmail.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
||||
* General Public License for more details.
|
||||
*/
|
||||
package org.meteoinfo.geometry.shape;
|
||||
* yaqiang.wang@gmail.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
||||
* General Public License for more details.
|
||||
*/
|
||||
package org.meteoinfo.geometry.shape;
|
||||
|
||||
import org.meteoinfo.common.PointD;
|
||||
import org.meteoinfo.geometry.geoprocess.GeometryUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Ellipse shape class
|
||||
*
|
||||
* @author Yaqiang Wang
|
||||
*/
|
||||
public class EllipseShape extends PolygonShape {
|
||||
// <editor-fold desc="Variables">
|
||||
private float angle = 0.0f;
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Constructor">
|
||||
* Ellipse shape class
|
||||
*
|
||||
* @author Yaqiang Wang
|
||||
*/
|
||||
public class EllipseShape extends PolygonShape {
|
||||
// <editor-fold desc="Variables">
|
||||
private float angle = 0.0f;
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Constructor">
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public EllipseShape() {
|
||||
}
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Get Set Methods">
|
||||
@Override
|
||||
public ShapeTypes getShapeType(){
|
||||
return ShapeTypes.ELLIPSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get angle
|
||||
* @return Angle
|
||||
*/
|
||||
public float getAngle(){
|
||||
return this.angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set angle
|
||||
* @param value Angle
|
||||
*/
|
||||
public void setAngle(float value){
|
||||
this.angle = value;
|
||||
}
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public EllipseShape() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone
|
||||
*
|
||||
* @return EllipseShape
|
||||
*/
|
||||
@Override
|
||||
public Object clone() {
|
||||
EllipseShape aPGS = new EllipseShape();
|
||||
aPGS.setExtent(this.getExtent());
|
||||
aPGS.setPoints(this.getPoints());
|
||||
aPGS.setVisible(this.isVisible());
|
||||
aPGS.setSelected(this.isSelected());
|
||||
|
||||
return aPGS;
|
||||
}
|
||||
// </editor-fold>
|
||||
}
|
||||
/**
|
||||
* Constructor
|
||||
* @param x Center x
|
||||
* @param y Center y
|
||||
* @param width Width
|
||||
* @param height Height
|
||||
*/
|
||||
public EllipseShape(double x, double y, double width, double height) {
|
||||
List<PointD> points = new ArrayList<>();
|
||||
points.add(new PointD(x - width * 0.5, y));
|
||||
points.add(new PointD(x, y - height * 0.5));
|
||||
points.add(new PointD(x + width * 0.5, y));
|
||||
points.add(new PointD(x, y + height * 0.5));
|
||||
super.setPoints(points);
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Get Set Methods">
|
||||
@Override
|
||||
public ShapeTypes getShapeType() {
|
||||
return ShapeTypes.ELLIPSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get center point
|
||||
* @return Center point
|
||||
*/
|
||||
public PointD getCenter() {
|
||||
return this.getExtent().getCenterPoint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get width
|
||||
* @return Width
|
||||
*/
|
||||
public double getWidth() {
|
||||
return this.getExtent().getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get height
|
||||
* @return Height
|
||||
*/
|
||||
public double getHeight() {
|
||||
return this.getExtent().getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get angle
|
||||
*
|
||||
* @return Angle
|
||||
*/
|
||||
public float getAngle() {
|
||||
return this.angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set angle
|
||||
*
|
||||
* @param value Angle
|
||||
*/
|
||||
public void setAngle(float value) {
|
||||
this.angle = value;
|
||||
}
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
|
||||
/**
|
||||
* Clone
|
||||
*
|
||||
* @return EllipseShape
|
||||
*/
|
||||
@Override
|
||||
public Object clone() {
|
||||
EllipseShape aPGS = new EllipseShape();
|
||||
aPGS.setExtent(this.getExtent());
|
||||
aPGS.setPoints(this.getPoints());
|
||||
aPGS.setVisible(this.isVisible());
|
||||
aPGS.setSelected(this.isSelected());
|
||||
|
||||
return aPGS;
|
||||
}
|
||||
// </editor-fold>
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ public class RectangleShape extends PolygonShape {
|
||||
private boolean round = false;
|
||||
private double roundX = 0;
|
||||
private double roundY = 0;
|
||||
private double angle = 0;
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Constructor">
|
||||
/**
|
||||
@ -100,6 +101,22 @@ public class RectangleShape extends PolygonShape {
|
||||
this.roundY = value;
|
||||
this.round = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get angle
|
||||
* @return Angle
|
||||
*/
|
||||
public double getAngle() {
|
||||
return this.angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set angle
|
||||
* @param value Angle
|
||||
*/
|
||||
public void setAngle(double value) {
|
||||
this.angle = value;
|
||||
}
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
|
||||
|
||||
@ -9,7 +9,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.meteoinfo.common.PointD;
|
||||
import org.meteoinfo.geometry.graphic.Graphic;
|
||||
import org.meteoinfo.geometry.legend.PolygonBreak;
|
||||
import org.meteoinfo.ndarray.Array;
|
||||
import org.meteoinfo.ndarray.IndexIterator;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -300,6 +303,63 @@ public class ShapeUtil {
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a polygon
|
||||
*
|
||||
* @param xa X coordinate array
|
||||
* @param ya Y coordinate array
|
||||
* @return PolygonShape
|
||||
*/
|
||||
public static PolygonShape createPolygon(Array xa, Array ya) {
|
||||
double x, y;
|
||||
int n = (int) xa.getSize();
|
||||
PolygonShape pgs;
|
||||
PointD p;
|
||||
List<PointD> points = new ArrayList<>();
|
||||
IndexIterator xIter = xa.getIndexIterator();
|
||||
IndexIterator yIter = ya.getIndexIterator();
|
||||
while (xIter.hasNext()){
|
||||
x = xIter.getDoubleNext();
|
||||
y = yIter.getDoubleNext();
|
||||
p = new PointD(x, y);
|
||||
points.add(p);
|
||||
}
|
||||
if (points.size() > 2) {
|
||||
pgs = new PolygonShape();
|
||||
pgs.setPoints(points);
|
||||
return pgs;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a polygon
|
||||
*
|
||||
* @param xa X coordinate array
|
||||
* @param ya Y coordinate array
|
||||
* @return PolygonShape
|
||||
*/
|
||||
public static PolygonShape createPolygonShape(Array xy) {
|
||||
double x, y;
|
||||
int n = xy.getShape()[0];
|
||||
PolygonShape pgs;
|
||||
PointD p;
|
||||
List<PointD> points = new ArrayList<>();
|
||||
IndexIterator iter = xy.getIndexIterator();
|
||||
while (iter.hasNext()){
|
||||
x = iter.getDoubleNext();
|
||||
y = iter.getDoubleNext();
|
||||
p = new PointD(x, y);
|
||||
points.add(p);
|
||||
}
|
||||
if (points.size() > 2) {
|
||||
pgs = new PolygonShape();
|
||||
pgs.setPoints(points);
|
||||
return pgs;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a circle
|
||||
|
||||
@ -1,32 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\common_math\special">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\calipso"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\patch">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\topology"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\test"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\stats"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\subplot"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\special"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\stats"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\maskout"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\patch"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf_sombrero.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\stats\kendalltau_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\special\erfc.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\map\maskout\maskout_data_circle_rect.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf_sombrero.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\stats\kendalltau_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\special\erfc.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\map\maskout\maskout_data_circle_rect.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -34,5 +32,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1364,813"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,693"/>
|
||||
</MeteoInfo>
|
||||
|
||||
Binary file not shown.
@ -10,6 +10,7 @@ import numbers
|
||||
|
||||
from org.meteoinfo.data.mapdata.geotiff import GeoTiff
|
||||
from org.meteoinfo.geometry.shape import ShapeUtil, PolygonShape
|
||||
from org.meteoinfo.geometry.graphic import Graphic
|
||||
from org.meteoinfo.geometry.legend import BreakTypes
|
||||
from org.meteoinfo.geometry.geoprocess import GeoComputation, GeometryUtil
|
||||
from org.meteoinfo.ndarray.math import ArrayMath, ArrayUtil
|
||||
@ -315,8 +316,8 @@ def maskout(data, mask, x=None, y=None):
|
||||
:returns: (*array_like*) Maskouted data array.
|
||||
"""
|
||||
if mask is None:
|
||||
return data
|
||||
elif isinstance(mask, (NDArray, DimArray)):
|
||||
return data
|
||||
elif isinstance(mask, NDArray):
|
||||
r = ArrayMath.maskout(data.asarray(), mask.asarray())
|
||||
if isinstance(data, DimArray):
|
||||
return DimArray(r, data.dims, data.fill_value, data.proj)
|
||||
@ -330,8 +331,14 @@ def maskout(data, mask, x=None, y=None):
|
||||
else:
|
||||
return None
|
||||
|
||||
if not isinstance(mask, (list, ArrayList)):
|
||||
if not isinstance(mask, (list, tuple, ArrayList)):
|
||||
if isinstance(mask, Graphic):
|
||||
mask = mask.getShape()
|
||||
mask = [mask]
|
||||
else:
|
||||
for i in range(len(mask)):
|
||||
if isinstance(mask[i], Graphic):
|
||||
mask[i] = mask[i].getShape()
|
||||
|
||||
if data.ndim == 2 and x.ndim == 1 and y.ndim == 1:
|
||||
x, y = np.meshgrid(x, y)
|
||||
|
||||
Binary file not shown.
@ -6,7 +6,9 @@ from ._axes3d import Axes3D
|
||||
from ._axes3dgl import Axes3DGL
|
||||
from ._figure import Figure
|
||||
from ._glfigure import GLFigure
|
||||
from .patches import *
|
||||
|
||||
|
||||
__all__ = ['Figure','GLFigure','Axes','PolarAxes','MapAxes','Axes3D','Axes3DGL']
|
||||
__all__ += miplot.__all__
|
||||
__all__ += miplot.__all__
|
||||
__all__ += patches.__all__
|
||||
Binary file not shown.
@ -929,6 +929,15 @@ class Axes(object):
|
||||
Reverse y axis.
|
||||
'''
|
||||
self.axes.getYAxis().setInverse(True)
|
||||
|
||||
def add_patch(self, patch):
|
||||
"""
|
||||
Add a patch.
|
||||
|
||||
:param patch: (*Graphic*) The patch to be added.
|
||||
"""
|
||||
self.axes.addGraphic(patch)
|
||||
self.axes.setAutoExtent()
|
||||
|
||||
def add_graphic(self, graphic):
|
||||
'''
|
||||
|
||||
138
meteoinfo-lab/pylib/mipylib/plotlib/patches.py
Normal file
138
meteoinfo-lab/pylib/mipylib/plotlib/patches.py
Normal file
@ -0,0 +1,138 @@
|
||||
from org.meteoinfo.geometry.graphic import Graphic
|
||||
from org.meteoinfo.geometry.shape import ShapeUtil, CircleShape, EllipseShape, \
|
||||
RectangleShape
|
||||
|
||||
from . import plotutil
|
||||
import mipylib.numeric as np
|
||||
|
||||
__all__ = ['Circle','Ellipse','Rectangle','Polygon']
|
||||
|
||||
class Circle(Graphic):
|
||||
"""
|
||||
A circle patch.
|
||||
"""
|
||||
|
||||
def __init__(self, xy, radius=5, **kwargs):
|
||||
"""
|
||||
Create a true circle at center *xy* = (*x*, *y*) with given *radius*.
|
||||
|
||||
:param xy: (float, float) xy coordinates of circle centre.
|
||||
:param radius: (float) Circle radius.
|
||||
"""
|
||||
self._center = xy
|
||||
self._radius = radius
|
||||
shape = CircleShape(xy[0], xy[1], radius)
|
||||
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
||||
super(Circle, self).__init__(shape, legend)
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
return self._center
|
||||
|
||||
@property
|
||||
def radius(self):
|
||||
return self._radius
|
||||
|
||||
class Ellipse(Graphic):
|
||||
"""
|
||||
A ellipse patch.
|
||||
"""
|
||||
|
||||
def __init__(self, xy, width, height, angle=0, **kwargs):
|
||||
"""
|
||||
Create a ellipse at center *xy* = (*x*, *y*) with given *width* and *height*.
|
||||
|
||||
:param xy: (float, float) xy coordinates of ellipse centre.
|
||||
:param width: (float) Ellipse width.
|
||||
:param height: (float) Ellipse height.
|
||||
:param angle: (float) Ellipse angle. Default is 0.
|
||||
"""
|
||||
self._center = xy
|
||||
self._width = width
|
||||
self._height = height
|
||||
self._angle = angle
|
||||
shape = EllipseShape(xy[0], xy[1], width, height)
|
||||
shape.setAngle(angle)
|
||||
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
||||
super(Ellipse, self).__init__(shape, legend)
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
return self._center
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return self._width
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self._height
|
||||
|
||||
@property
|
||||
def angle(self):
|
||||
return self._angle
|
||||
|
||||
class Rectangle(Graphic):
|
||||
"""
|
||||
A rectangle patch.
|
||||
"""
|
||||
|
||||
def __init__(self, xy, width, height, angle=0, **kwargs):
|
||||
"""
|
||||
Create a rectangle at anchor point *xy* = (*x*, *y*) with given *width* and *height*.
|
||||
|
||||
:param xy: (float, float) xy coordinates of anchor point.
|
||||
:param width: (float) Rectangle width.
|
||||
:param height: (float) Rectangle height.
|
||||
:param angle: (float) Rectangle angle. Default is 0.
|
||||
"""
|
||||
self._center = xy
|
||||
self._width = width
|
||||
self._height = height
|
||||
self._angle = angle
|
||||
shape = RectangleShape(xy[0], xy[1], width, height)
|
||||
shape.setAngle(angle)
|
||||
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
||||
super(Rectangle, self).__init__(shape, legend)
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
return self._center
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return self._width
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self._height
|
||||
|
||||
@property
|
||||
def angle(self):
|
||||
return self._angle
|
||||
|
||||
class Polygon(Graphic):
|
||||
"""
|
||||
A general polygon patch.
|
||||
"""
|
||||
|
||||
def __init__(self, xy, closed=True, **kwargs):
|
||||
"""
|
||||
Create a polygon with *xy* point array.
|
||||
|
||||
:param xy: (array_like) xy point array.
|
||||
:param closed: (bool) If *closed* is *True*, the polygon will be closed so the
|
||||
starting and ending points are the same.
|
||||
"""
|
||||
if isinstance(xy, (list, tuple)):
|
||||
xy = np.array(xy)
|
||||
|
||||
self._xy = xy
|
||||
self._closed = closed
|
||||
shape = ShapeUtil.createPolygonShape(xy._array)
|
||||
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
||||
super(Polygon, self).__init__(shape, legend)
|
||||
|
||||
@property
|
||||
def xy(self):
|
||||
return self._xy
|
||||
Loading…
x
Reference in New Issue
Block a user