mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
add 2D streamplot function in 3D axes
This commit is contained in:
parent
ead8103231
commit
eecbd206bf
@ -6992,26 +6992,158 @@ public class GraphicFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create stream line
|
||||
* Create streamline
|
||||
*
|
||||
* @param xdata X data array
|
||||
* @param ydata Y data array
|
||||
* @param udata U/WindDirection data array
|
||||
* @param vdata V/WindSpeed data array
|
||||
* @param cdata Color value data array
|
||||
* @param density Streamline density
|
||||
* @param slb Streamline break
|
||||
* @param ls Legend scheme
|
||||
* @param isUV Is U/V or not
|
||||
* @return GraphicCollection
|
||||
* @param offset Offset in z direction
|
||||
* @param zdir Z direction - x, y or z
|
||||
* @return GraphicCollection3D
|
||||
*/
|
||||
public static GraphicCollection createStreamlines(Array xdata, Array ydata, Array udata, Array vdata,
|
||||
int density, StreamlineBreak slb, boolean isUV) {
|
||||
GraphicCollection gc = new GraphicCollection();
|
||||
public static GraphicCollection3D createStreamlines(Array xdata, Array ydata, Array udata, Array vdata,
|
||||
Array cdata, int density, LegendScheme ls, boolean isUV, double offset, String zdir) {
|
||||
GraphicCollection3D graphics = new GraphicCollection3D();
|
||||
if (!isUV) {
|
||||
Array[] uvData = MeteoMath.ds2uv(udata, vdata);
|
||||
udata = uvData[0];
|
||||
vdata = uvData[1];
|
||||
}
|
||||
|
||||
double[][] u = (double[][])ArrayUtil.copyToNDJavaArray_Double(udata);
|
||||
double[][] v = (double[][])ArrayUtil.copyToNDJavaArray_Double(vdata);
|
||||
double[] x = (double[]) ArrayUtil.copyToNDJavaArray_Double(xdata);
|
||||
double[] y = (double[]) ArrayUtil.copyToNDJavaArray_Double(ydata);
|
||||
List<PolyLine> streamlines = Contour.tracingStreamline(u, v,
|
||||
x, y, density);
|
||||
|
||||
int ny = u.length;
|
||||
int nx = u[0].length;
|
||||
ColorBreak cb = ls.getLegendBreak(0);
|
||||
if (cdata == null) {
|
||||
for (PolyLine line : streamlines) {
|
||||
PolylineZShape shape = new PolylineZShape();
|
||||
List<PointZ> points = new ArrayList<>();
|
||||
PointZ p;
|
||||
if (zdir.equals("x")) {
|
||||
for (int j = 0; j < line.PointList.size(); j++) {
|
||||
p = new PointZ();
|
||||
p.Y = (line.PointList.get(j)).X;
|
||||
p.Z = (line.PointList.get(j)).Y;
|
||||
p.X = offset;
|
||||
points.add(p);
|
||||
}
|
||||
} else if (zdir.equals("y")) {
|
||||
for (int j = 0; j < line.PointList.size(); j++) {
|
||||
p = new PointZ();
|
||||
p.X = (line.PointList.get(j)).X;
|
||||
p.Z = (line.PointList.get(j)).Y;
|
||||
p.Y = offset;
|
||||
points.add(p);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < line.PointList.size(); j++) {
|
||||
p = new PointZ();
|
||||
p.X = (line.PointList.get(j)).X;
|
||||
p.Y = (line.PointList.get(j)).Y;
|
||||
p.Z = offset;
|
||||
points.add(p);
|
||||
}
|
||||
}
|
||||
shape.setPoints(points);
|
||||
graphics.add(new Graphic(shape, cb));
|
||||
}
|
||||
} else {
|
||||
cdata = cdata.copyIfView();
|
||||
for (PolyLine line : streamlines) {
|
||||
PolylineZShape shape = new PolylineZShape();
|
||||
List<PointZ> points = new ArrayList<>();
|
||||
PointZ p;
|
||||
ColorBreakCollection cbs = new ColorBreakCollection();
|
||||
if (zdir.equals("x")) {
|
||||
for (int j = 0; j < line.PointList.size(); j++) {
|
||||
p = new PointZ();
|
||||
p.Y = (line.PointList.get(j)).X;
|
||||
p.Z = (line.PointList.get(j)).Y;
|
||||
p.X = offset;
|
||||
int[] idx = ArrayUtil.gridIndex(xdata, ydata, p.Y, p.Z);
|
||||
if (idx != null) {
|
||||
int yi = idx[0];
|
||||
int xi = idx[1];
|
||||
p.M = cdata.getDouble(yi * nx + xi);
|
||||
}
|
||||
cb = ls.findLegendBreak(p.M);
|
||||
cbs.add(cb);
|
||||
points.add(p);
|
||||
}
|
||||
} else if (zdir.equals("y")) {
|
||||
for (int j = 0; j < line.PointList.size(); j++) {
|
||||
p = new PointZ();
|
||||
p.X = (line.PointList.get(j)).X;
|
||||
p.Z = (line.PointList.get(j)).Y;
|
||||
p.Y = offset;
|
||||
int[] idx = ArrayUtil.gridIndex(xdata, ydata, p.X, p.Z);
|
||||
if (idx != null) {
|
||||
int yi = idx[0];
|
||||
int xi = idx[1];
|
||||
p.M = cdata.getDouble(yi * nx + xi);
|
||||
}
|
||||
cb = ls.findLegendBreak(p.M);
|
||||
cbs.add(cb);
|
||||
points.add(p);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < line.PointList.size(); j++) {
|
||||
p = new PointZ();
|
||||
p.X = (line.PointList.get(j)).X;
|
||||
p.Y = (line.PointList.get(j)).Y;
|
||||
p.Z = offset;
|
||||
int[] idx = ArrayUtil.gridIndex(xdata, ydata, p.X, p.Y);
|
||||
if (idx != null) {
|
||||
int yi = idx[0];
|
||||
int xi = idx[1];
|
||||
p.M = cdata.getDouble(yi * nx + xi);
|
||||
}
|
||||
cb = ls.findLegendBreak(p.M);
|
||||
cbs.add(cb);
|
||||
points.add(p);
|
||||
}
|
||||
}
|
||||
shape.setPoints(points);
|
||||
graphics.add(new Graphic(shape, cbs));
|
||||
}
|
||||
}
|
||||
graphics.setLegendScheme(ls);
|
||||
|
||||
return graphics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create streamline
|
||||
*
|
||||
* @param xdata X data array
|
||||
* @param ydata Y data array
|
||||
* @param udata U/WindDirection data array
|
||||
* @param vdata V/WindSpeed data array
|
||||
* @param density Streamline density
|
||||
* @param slb Streamline break
|
||||
* @param isUV Is U/V or not
|
||||
* @return GraphicCollection
|
||||
*/
|
||||
public static GraphicCollection createStreamlines(Array xdata, Array ydata, Array udata, Array vdata,
|
||||
int density, StreamlineBreak slb, boolean isUV) {
|
||||
GraphicCollection gc = new GraphicCollection();
|
||||
if (!isUV) {
|
||||
Array[] uvData = MeteoMath.ds2uv(udata, vdata);
|
||||
udata = uvData[0];
|
||||
vdata = uvData[1];
|
||||
}
|
||||
|
||||
double[][] u = (double[][])ArrayUtil.copyToNDJavaArray_Double(udata);
|
||||
double[][] v = (double[][])ArrayUtil.copyToNDJavaArray_Double(vdata);
|
||||
double[] x = (double[]) ArrayUtil.copyToNDJavaArray_Double(xdata);
|
||||
@ -7019,7 +7151,7 @@ public class GraphicFactory {
|
||||
List<PolyLine> streamlines = Contour.tracingStreamline(u, v,
|
||||
x, y, density);
|
||||
PolyLine line;
|
||||
for (int i = 0; i < streamlines.size() - 1; i++) {
|
||||
for (int i = 0; i < streamlines.size(); i++) {
|
||||
line = streamlines.get(i);
|
||||
PolylineShape aPolyline = new PolylineShape();
|
||||
PointD aPoint;
|
||||
@ -7039,7 +7171,7 @@ public class GraphicFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace streamlines
|
||||
* Trace 3D streamlines
|
||||
* @param xa X coordinate array
|
||||
* @param ya Y coordinate array
|
||||
* @param z Z value
|
||||
@ -7174,7 +7306,7 @@ public class GraphicFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace streamlines
|
||||
* Trace 3D streamlines
|
||||
* @param xa X coordinate array
|
||||
* @param ya Y coordinate array
|
||||
* @param xySlice XY slice value - [x1,y1,x2,y2]
|
||||
|
||||
@ -1,14 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\dataframe">
|
||||
<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\funny"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\wind">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\calc"/>
|
||||
@ -16,21 +10,27 @@
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\savefig"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/>
|
||||
</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\compare_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\dataframe\compare_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour\contour3_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot\streamplot_3.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot\streamplot_2d_1.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\compare_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\dataframe\compare_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour\contour3_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot\streamplot_3.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot\streamplot_2d_1.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -38,5 +38,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1421,827"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
|
||||
</MeteoInfo>
|
||||
|
||||
Binary file not shown.
@ -3703,7 +3703,7 @@ class Axes(object):
|
||||
|
||||
def streamplot(self, *args, **kwargs):
|
||||
"""
|
||||
Plot 3D streamline.
|
||||
Plot 2D streamline.
|
||||
|
||||
:param x: (*array_like*) Optional. X coordinate array.
|
||||
:param y: (*array_like*) Optional. Y coordinate array.
|
||||
@ -3716,7 +3716,7 @@ class Axes(object):
|
||||
:param density: (*int*) Streamline density. Default is 4.
|
||||
:param zorder: (*int*) Z-order of streamline graphic for display.
|
||||
|
||||
:returns: (*graphics*) 3D streamline graphics.
|
||||
:returns: (*graphics*) 2D streamline graphics.
|
||||
"""
|
||||
isuv = kwargs.pop('isuv', True)
|
||||
density = kwargs.pop('density', 4)
|
||||
|
||||
Binary file not shown.
@ -502,6 +502,107 @@ class Axes3DGL(Axes3D):
|
||||
return barbreaks
|
||||
|
||||
def streamplot(self, *args, **kwargs):
|
||||
"""
|
||||
Plot 2D streamline.
|
||||
|
||||
:param x: (*array_like*) Optional. X coordinate array.
|
||||
:param y: (*array_like*) Optional. Y coordinate array.
|
||||
:param u: (*array_like*) U component of the arrow vectors (wind field) or wind direction.
|
||||
:param v: (*array_like*) V component of the arrow vectors (wind field) or wind speed.
|
||||
:param z: (*array_like*) Optional, 2-D z value array.
|
||||
:param color: (*Color*) Streamline color.
|
||||
:param fill_value: (*float*) Fill_value. Default is ``-9999.0``.
|
||||
:param isuv: (*boolean*) Is U/V or direction/speed data array pairs. Default is True.
|
||||
:param density: (*int*) Streamline density. Default is 4.
|
||||
:param offset: (*float*) Z direction offset. Default is 0.
|
||||
:param zdir: (*int*) Z direction ['x'|'y'|'z']. Default is `z`.
|
||||
|
||||
:returns: (*graphics*) 2D streamline graphics.
|
||||
"""
|
||||
ls = kwargs.pop('symbolspec', None)
|
||||
cmap = plotutil.getcolormap(**kwargs)
|
||||
density = kwargs.pop('density', 4)
|
||||
iscolor = False
|
||||
cdata = None
|
||||
if len(args) < 4:
|
||||
u = args[0]
|
||||
v = args[1]
|
||||
u = np.asarray(u)
|
||||
nz, ny, nx = u.shape
|
||||
x = np.arange(nx)
|
||||
y = np.arange(ny)
|
||||
args = args[2:]
|
||||
else:
|
||||
x = args[0]
|
||||
y = args[1]
|
||||
u = args[2]
|
||||
v = args[3]
|
||||
args = args[4:]
|
||||
if len(args) > 0:
|
||||
cdata = args[0]
|
||||
iscolor = True
|
||||
args = args[1:]
|
||||
x = plotutil.getplotdata(x)
|
||||
y = plotutil.getplotdata(y)
|
||||
u = plotutil.getplotdata(u)
|
||||
v = plotutil.getplotdata(v)
|
||||
|
||||
if ls is None:
|
||||
if iscolor:
|
||||
if len(args) > 0:
|
||||
cn = args[0]
|
||||
if isinstance(cn, NDArray):
|
||||
cn = cn.aslist()
|
||||
ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), cn, cmap)
|
||||
else:
|
||||
levs = kwargs.pop('levels', None)
|
||||
if levs is None:
|
||||
ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), cmap)
|
||||
else:
|
||||
if isinstance(levs, NDArray):
|
||||
levs = levs.tolist()
|
||||
ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), levs, cmap)
|
||||
else:
|
||||
if cmap.getColorCount() == 1:
|
||||
c = cmap.getColor(0)
|
||||
else:
|
||||
c = Color.black
|
||||
ls = LegendManage.createSingleSymbolLegendScheme(ShapeTypes.POLYLINE, c, 1)
|
||||
ls = plotutil.setlegendscheme_line(ls, **kwargs)
|
||||
|
||||
if not kwargs.has_key('headwidth'):
|
||||
kwargs['headwidth'] = 1
|
||||
if not kwargs.has_key('headlength'):
|
||||
kwargs['headlength'] = 2.5 * kwargs['headwidth']
|
||||
for i in range(ls.getBreakNum()):
|
||||
lb = plotutil.line2stream(ls.getLegendBreak(i), **kwargs)
|
||||
ls.setLegendBreak(i, lb)
|
||||
|
||||
if not cdata is None:
|
||||
cdata = plotutil.getplotdata(cdata)
|
||||
|
||||
isuv = kwargs.pop('isuv', True)
|
||||
offset = kwargs.pop('offset', 0)
|
||||
zdir = kwargs.pop('zdir', 'z')
|
||||
graphics = GraphicFactory.createStreamlines(x, y, u, v, cdata, density, ls, isuv,
|
||||
offset, zdir)
|
||||
|
||||
lighting = kwargs.pop('lighting', None)
|
||||
if not lighting is None:
|
||||
graphics.setUsingLight(lighting)
|
||||
|
||||
# Pipe
|
||||
pipe = kwargs.pop('pipe', False)
|
||||
if pipe:
|
||||
radius = kwargs.pop('radius', 0.02)
|
||||
steps = kwargs.pop('steps', 48)
|
||||
graphics = GraphicFactory.lineString3DToPipe(graphics, radius, steps)
|
||||
|
||||
self.add_graphic(graphics)
|
||||
|
||||
return graphics
|
||||
|
||||
def streamplot3(self, *args, **kwargs):
|
||||
"""
|
||||
Plot streamlines in 3D axes.
|
||||
|
||||
|
||||
Binary file not shown.
@ -1670,7 +1670,7 @@ def scatterm(*args, **kwargs):
|
||||
return r
|
||||
|
||||
|
||||
@_copy_docstring_and_deprecators(Axes3D.streamplot)
|
||||
@_copy_docstring_and_deprecators(Axes3DGL.streamplot3)
|
||||
def streamplot3(*args, **kwargs):
|
||||
global g_axes
|
||||
if g_axes is None:
|
||||
@ -1679,7 +1679,7 @@ def streamplot3(*args, **kwargs):
|
||||
if not isinstance(g_axes, Axes3DGL):
|
||||
g_axes = axes3dgl()
|
||||
|
||||
r = g_axes.streamplot(*args, **kwargs)
|
||||
r = g_axes.streamplot3(*args, **kwargs)
|
||||
draw_if_interactive()
|
||||
return r
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user