add contour3 plot function

This commit is contained in:
wyq 2023-06-14 16:00:51 +08:00
parent 37fb27ed17
commit 40d21f0e76
8 changed files with 215 additions and 7 deletions

View File

@ -3673,6 +3673,81 @@ public class GraphicFactory {
return graphics;
}
/**
* Create 3-D contour lines
*
* @param xa X coordinate array - one dimension
* @param ya Y coordinate array - one dimension
* @param za Z coordinate array - two dimension
* @param ls Legend scheme
* @param isSmooth Is smooth or not
* @return Contour lines
*/
public static GraphicCollection createContourLines3D(Array xa, Array ya, Array za, LegendScheme ls, boolean isSmooth) {
xa = xa.copyIfView();
ya = ya.copyIfView();
za = za.copyIfView();
ls = ls.convertTo(ShapeTypes.POLYLINE);
Object[] ccs = LegendManage.getContoursAndColors(ls);
double[] cValues = (double[]) ccs[0];
int[] shape = za.getShape();
int[][] S1 = new int[shape[0]][shape[1]];
double[] x = (double[])ArrayUtil.copyToNDJavaArray_Double(xa);
double[] y = (double[])ArrayUtil.copyToNDJavaArray_Double(ya);
if (x[1] - x[0] < 0) {
ArrayUtils.reverse(x);
za = za.flip(1);
}
if (y[1] - y[0] < 0) {
ArrayUtils.reverse(y);
za = za.flip(0);
}
double missingValue = -9999.0;
double[][] data = (double[][]) ArrayUtil.copyToNDJavaArray_Double(za, missingValue);
Object[] cbs = ContourDraw.tracingContourLines(data,
cValues, x, y, missingValue, S1);
List<PolyLine> ContourLines = (List<PolyLine>) cbs[0];
if (ContourLines.isEmpty()) {
return null;
}
if (isSmooth) {
ContourLines = Contour.smoothLines(ContourLines);
}
PolyLine aLine;
double v;
ColorBreak cbb;
GraphicCollection3D graphics = new GraphicCollection3D();
BivariateFunction interpolator = InterpUtil.getBiInterpFunc(xa, ya, za.transpose(0, 1), "linear");
for (int i = 0; i < ContourLines.size(); i++) {
aLine = ContourLines.get(i);
v = aLine.Value;
PolylineZShape aPolyline = new PolylineZShape();
PointZ aPoint;
List<PointZ> pList = new ArrayList<>();
for (int j = 0; j < aLine.PointList.size(); j++) {
aPoint = new PointZ();
aPoint.X = aLine.PointList.get(j).X;
aPoint.Y = aLine.PointList.get(j).Y;
aPoint.Z = interpolator.value(aPoint.X, aPoint.Y);
pList.add(aPoint);
}
aPolyline.setPoints(pList);
aPolyline.setValue(v);
cbb = ls.findLegendBreak(v);
graphics.add(new Graphic(aPolyline, cbb));
}
graphics.setSingleLegend(false);
graphics.setLegendScheme(ls);
return graphics;
}
/**
* Create contour lines
*

View File

@ -1,36 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\dataframe">
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\burf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW\ZhengZhou"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\slice"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
<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\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\dataframe\loc_2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\dataframe\replace_3.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\dataframe\loc_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\dataframe\replace_4.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\dataframe\loc_2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\dataframe\replace_3.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\dataframe\loc_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\dataframe\replace_4.py"/>
</RecentFiles>
</File>
<Font>

View File

@ -1265,6 +1265,74 @@ class Axes3D(Axes):
if visible:
self.add_graphic(igraphic)
return igraphic
def contour3(self, *args, **kwargs):
"""
3-D contour plot.
:param x: (*array_like*) Optional. X coordinate array.
:param y: (*array_like*) Optional. Y coordinate array.
:param z: (*array_like*) 2-D z value array.
:param levels: (*array_like*) Optional. A list of floating point numbers indicating the level curves
to draw, in increasing order.
:param cmap: (*string*) Color map string.
:param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a
string, like r or red, all levels will be plotted in this color. If a tuple of matplotlib
color args (string, float, rgb, etc), different levels will be plotted in different colors in
the order specified.
:param smooth: (*boolean*) Smooth contour lines or not.
:returns: (*graphics*) Contour graphics created from array data.
"""
n = len(args)
cmap = plotutil.getcolormap(**kwargs)
fill_value = kwargs.pop('fill_value', -9999.0)
offset = kwargs.pop('offset', 0)
if n <= 2:
z = args[0]
if isinstance(z, DimArray):
y = z.dimvalue(0)
x = z.dimvalue(1)
else:
x = np.arange(z.shape[1])
y = np.arange(z.shape[0])
args = args[1:]
else:
x = args[0]
y = args[1]
z = args[2]
args = args[3:]
if x.ndim == 2:
x = x[0]
if y.ndim == 2:
y = y[:,0]
if len(args) > 0:
level_arg = args[0]
if isinstance(level_arg, int):
cn = level_arg
ls = LegendManage.createLegendScheme(z.min(), z.max(), cn, cmap)
else:
if isinstance(level_arg, NDArray):
level_arg = level_arg.aslist()
ls = LegendManage.createLegendScheme(z.min(), z.max(), level_arg, cmap)
else:
ls = LegendManage.createLegendScheme(z.min(), z.max(), cmap)
ls = ls.convertTo(ShapeTypes.POLYLINE)
plotutil.setlegendscheme(ls, **kwargs)
smooth = kwargs.pop('smooth', True)
igraphic = GraphicFactory.createContourLines3D(x.asarray(), y.asarray(), z.asarray(), ls, smooth)
lighting = kwargs.pop('lighting', None)
if not lighting is None:
igraphic.setUsingLight(lighting)
visible = kwargs.pop('visible', True)
if visible:
self.add_graphic(igraphic)
return igraphic
def contourf(self, *args, **kwargs):
"""

View File

@ -41,7 +41,7 @@ g_axes = None
__all__ = [
'annotate', 'antialias', 'arrow', 'arrowline', 'axes', 'axes3d', 'axes3dgl', 'axesm', 'caxes', 'axis',
'axism', 'bar', 'bar3', 'barh', 'barbs', 'barbsm', 'bgcolor', 'box', 'boxplot', 'windrose', 'cla',
'clabel', 'clc', 'clear', 'clf', 'cll', 'cloudspec', 'colorbar', 'contour', 'contourf',
'clabel', 'clc', 'clear', 'clf', 'cll', 'cloudspec', 'colorbar', 'contour', 'contour3', 'contourf',
'contourfm', 'contourm', 'contourfslice', 'contourslice', 'delfig', 'draw', 'draw_if_interactive',
'errorbar', 'figure', 'glfigure', 'figsize', 'patch', 'rectangle', 'fill', 'fill3', 'fill_between',
'fill_betweenx', 'fimplicit3', 'webmap', 'gca', 'gcf', 'gc_collect', 'geoshow', 'get_figure',
@ -2079,6 +2079,20 @@ def slice3(*args, **kwargs):
return r
@_copy_docstring_and_deprecators(Axes3D.contour3)
def contour3(*args, **kwargs):
global g_axes
if g_axes is None:
g_axes = axes3d()
else:
if not isinstance(g_axes, Axes3DGL):
g_axes = axes3dgl()
r = g_axes.contour3(*args, **kwargs)
draw_if_interactive()
return r
@_copy_docstring_and_deprecators(Axes3DGL.contourslice)
def contourslice(*args, **kwargs):
global g_axes

View File

@ -224,6 +224,30 @@ public enum DataType {
return (this == DataType.ENUM1) || (this == DataType.ENUM2) || (this == DataType.ENUM4);
}
/**
* Convert a number to this data type
* @param n The number
* @return New data type number
*/
public Number asNumber(Number n) {
switch (this) {
case INT:
return n.intValue();
case BYTE:
return n.byteValue();
case FLOAT:
return n.floatValue();
case DOUBLE:
return n.doubleValue();
case SHORT:
return n.shortValue();
case LONG:
return n.longValue();
default:
return n;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
/**
* Find the DataType that matches this name.
@ -379,7 +403,6 @@ public enum DataType {
static public short unsignedByteToShort(byte b) {
return (short) (b & 0xff);
}
// return (short)((b<0)? (short)b + 256 : (short)b);
public static void main(String[] args) {
for (int i = 0; i < 260; i++) {

View File

@ -8597,6 +8597,9 @@ public class ArrayMath {
* @param value New value
*/
public static void replaceValue(Array a, Object oValue, Object value) {
if (oValue instanceof Number) {
oValue = a.getDataType().asNumber((Number) oValue);
}
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
if (oValue.equals(a.getObject(i))) {
@ -8652,6 +8655,31 @@ public class ArrayMath {
return n;
}
/**
* Convert a number to data type
* @param v Number value
* @param dt Data type
* @return Number
*/
public static Number toDataType(Number v, DataType dt) {
switch (dt) {
case INT:
case BOOLEAN:
return v.intValue();
case FLOAT:
return v.floatValue();
case SHORT:
return v.shortValue();
case BYTE:
return v.byteValue();
case LONG:
return v.longValue();
case DOUBLE:
return v.doubleValue();
}
return v;
}
// </editor-fold>
// <editor-fold desc="Location">
/**