diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/axis/Axis.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/axis/Axis.java index 92df00e7..1ea693d8 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/axis/Axis.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/axis/Axis.java @@ -1075,18 +1075,13 @@ public void setMinMaxValue(double minValue, double maxValue) { } updateTickValues(); -// if (this.timeAxis) { -// this.updateTimeLabels(); -// } else { -// tickValues = MIMath.getIntervalValues(minValue, maxValue); -// } } /** * Update tick values */ public void updateTickValues() { - List r = MIMath.getIntervalValues1(minValue, maxValue); + List r = MIMath.getIntervalValuesAxis(minValue, maxValue); this.tickValues = (double[]) r.get(0); this.tickDeltaValue = (Double) r.get(1); } diff --git a/meteoinfo-common/src/main/java/org/meteoinfo/common/MIMath.java b/meteoinfo-common/src/main/java/org/meteoinfo/common/MIMath.java index 3f809fd6..ba1469a4 100644 --- a/meteoinfo-common/src/main/java/org/meteoinfo/common/MIMath.java +++ b/meteoinfo-common/src/main/java/org/meteoinfo/common/MIMath.java @@ -964,6 +964,103 @@ public static List getIntervalValues1(double min, double max) { return getIntervalValues(min, max, false); } + /** + * Create contour values by minimum and maximum values + * + * @param min Minimum value + * @param max Maximum value + * @return Contour values + */ + public static List getIntervalValuesAxis(double min, double max) { + return getIntervalValuesAxis(min, max, false); + } + + /** + * Create contour values by minimum and maximum values + * + * @param min Minimum value + * @param max Maximum value + * @param isExtend If extend values + * @return Contour values + */ + public static List getIntervalValuesAxis(double min, double max, boolean isExtend) { + int i, cNum, aD, aE; + double cDelt, range, newMin; + String eStr; + List r = new ArrayList<>(); + + range = BigDecimalUtil.sub(max, min); + if (range == 0.0) { + r.add(new double[]{min}); + r.add(0.0); + return r; + } else if (range < 0) { + range = -range; + double temp = min; + min = max; + max = temp; + } + + eStr = String.format("%1$E", range); + aD = Integer.parseInt(eStr.substring(0, 1)); + aE = (int) Math.floor(Math.log10(range)); + int nMin = 4; + if (aD >= nMin) { + cDelt = BigDecimalUtil.pow(10, aE); + cNum = aD; + } else { + double cd = BigDecimalUtil.pow(10, aE - 1); + i = 5; + cDelt = BigDecimalUtil.mul(i, cd); + cNum = (int) (range / cDelt); + while (cNum < nMin && i > 1) { + i--; + cDelt = BigDecimalUtil.mul(i, cd); + cNum = (int) (range / cDelt); + } + } + int temp = (int) (min / cDelt + 1); + newMin = BigDecimalUtil.mul(temp, cDelt); + if (newMin - min >= cDelt) { + newMin = BigDecimalUtil.sub(newMin, cDelt); + cNum += 1; + } + + if (newMin + (cNum - 1) * cDelt > max) { + cNum -= 1; + } else if (newMin + (cNum - 1) * cDelt + cDelt < max) { + cNum += 1; + } + + //Get values + List values = new ArrayList<>(); + double v; + for (i = 0; i < cNum; i++) { + v = BigDecimalUtil.add(newMin, BigDecimalUtil.mul(i, cDelt)); + if (v >= min && v <= max) + values.add(v); + } + + //Extend values + if (isExtend) { + if (values.get(0) > min) { + values.add(0, BigDecimalUtil.sub(newMin, cDelt)); + } + if (values.get(values.size() - 1) < max) { + values.add(BigDecimalUtil.add(values.get(values.size() - 1), cDelt)); + } + } + + double[] cValues = new double[values.size()]; + for (i = 0; i < values.size(); i++) { + cValues[i] = values.get(i); + } + + r.add(cValues); + r.add(cDelt); + return r; + } + /** * Create contour values by minimum and maximum values * @@ -993,29 +1090,15 @@ public static List getIntervalValues(double min, double max, boolean isE eStr = String.format("%1$E", range); aD = Integer.parseInt(eStr.substring(0, 1)); aE = (int) Math.floor(Math.log10(range)); -// int idx = eStr.indexOf("E"); -// if (idx < 0) { -// aE = 0; -// } else { -// aE = Integer.parseInt(eStr.substring(eStr.indexOf("E") + 1)); -// } if (aD > 5) { - //cDelt = Math.pow(10, aE); cDelt = BigDecimalUtil.pow(10, aE); cNum = aD; - //newMin = Convert.ToInt32((min + cDelt) / Math.Pow(10, aE)) * Math.Pow(10, aE); - //newMin = (int) (min / cDelt + 1) * cDelt; } else if (aD == 5) { - //cDelt = aD * Math.pow(10, aE - 1); cDelt = aD * BigDecimalUtil.pow(10, aE - 1); cNum = 10; - //newMin = Convert.ToInt32((min + cDelt) / Math.Pow(10, aE)) * Math.Pow(10, aE); - //newMin = (int) (min / cDelt + 1) * cDelt; cNum++; } else { - //cDelt = aD * Math.pow(10, aE - 1); double cd = BigDecimalUtil.pow(10, aE - 1); - //cDelt = BigDecimalUtil.mul(aD, cDelt); cDelt = BigDecimalUtil.mul(5, cd); cNum = (int) (range / cDelt); if (cNum < 5) { @@ -1026,8 +1109,6 @@ public static List getIntervalValues(double min, double max, boolean isE cNum = (int) (range / cDelt); } } - //newMin = Convert.ToInt32((min + cDelt) / Math.Pow(10, aE - 1)) * Math.Pow(10, aE - 1); - //newMin = (int) (min / cDelt + 1) * cDelt; } int temp = (int) (min / cDelt + 1); newMin = BigDecimalUtil.mul(temp, cDelt); diff --git a/meteoinfo-lab/milconfig.xml b/meteoinfo-lab/milconfig.xml index 02fe616c..a80f9368 100644 --- a/meteoinfo-lab/milconfig.xml +++ b/meteoinfo-lab/milconfig.xml @@ -1,8 +1,6 @@ - - - + @@ -10,25 +8,29 @@ - + + + - - + + + - - + + + @@ -36,5 +38,5 @@
- + diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d$py.class index 8c17e092..b5453af8 100644 Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d$py.class differ diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d.py b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d.py index a3b3e050..685f9d1e 100644 --- a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d.py +++ b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d.py @@ -1146,11 +1146,17 @@ def contour(self, *args, **kwargs): x = np.arange(a.shape[1]) y = np.arange(a.shape[0]) args = args[1:] - elif n <=4: + else: x = args[0] y = args[1] a = 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): @@ -1214,11 +1220,17 @@ def contourf(self, *args, **kwargs): x = np.arange(a.shape[1]) y = np.arange(a.shape[0]) args = args[1:] - elif n <=4: + else: x = args[0] y = args[1] a = 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): diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class index 135b41e4..78a27be4 100644 Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class differ diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py index 98c07008..24fb129c 100644 --- a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py +++ b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py @@ -1138,6 +1138,40 @@ def mesh(self, *args, **kwargs): self.add_graphic(graphics) return graphics + def meshc(self, *args, **kwargs): + """ + Contour plot under mesh surface 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 cmap: (*string*) Color map string. + + :returns: 3D mesh and contour graphics. + """ + if len(args) <= 2: + z = args[0] + if isinstance(z, DimArray): + x = args[0].dimvalue(1) + y = args[0].dimvalue(0) + else: + ny, nx = z.shape + x = np.arange(nx) + y = np.arange(ny) + x, y = np.meshgrid(x, y) + args1 = [x, y, z] + args[1:] + else: + args1 = args + + gmesh = self.mesh(*args1, **kwargs) + zmin = args1[2].min() + + kwargs['offset'] = zmin + args1 = args1[:3] + gcontour = self.contour(*args1, **kwargs) + + return gmesh, gcontour + def surf(self, *args, **kwargs): """ creates a three-dimensional surface plot @@ -1253,6 +1287,41 @@ def surf(self, *args, **kwargs): self.add_graphic(graphics) return graphics + def surfc(self, *args, **kwargs): + """ + Contour plot under surface 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 cmap: (*string*) Color map string. + :param lighting: (*bool*) Using light or not. + + :returns: 3D surface and contour graphics. + """ + if len(args) <= 2: + z = args[0] + if isinstance(z, DimArray): + x = args[0].dimvalue(1) + y = args[0].dimvalue(0) + else: + ny, nx = z.shape + x = np.arange(nx) + y = np.arange(ny) + x, y = np.meshgrid(x, y) + args1 = [x, y, z] + args[1:] + else: + args1 = args + + gsurf = self.surf(*args1, **kwargs) + zmin = args1[2].min() + + kwargs['offset'] = zmin + args1 = args1[:3] + gcontour = self.contour(*args1, **kwargs) + + return gsurf, gcontour + def plot_surface(self, *args, **kwargs): """ creates a three-dimensional surface plot diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class index 94d2e929..4e0726fa 100644 Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class differ diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py b/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py index 1a57bdf1..4d0e9875 100644 --- a/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py +++ b/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py @@ -40,25 +40,21 @@ __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', - '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', 'gifaddframe', 'gifanimation', 'giffinish', - 'grid', 'gridshow', 'gridshowm', 'hist', 'imshow', 'imshowm', 'isosurface', 'legend', 'left_title', 'lighting', - 'loglog', 'makecolors', - 'makelegend', 'makesymbolspec', 'masklayer', 'material', 'mesh', 'model', 'particles', 'pcolor', 'pcolorm', 'pie', 'plot', - 'plot3', 'plotm', 'quiver', 'quiver3', - 'quiverkey', 'quiverm', 'readlegend', 'right_title', 'refresh', 'savefig', 'savefig_jpeg', 'scatter', 'scatter3', - 'scatterm', - 'semilogx', 'semilogy', 'show', 'slice3', 'stationmodel', 'stem', 'stem3', 'step', 'streamplot', 'streamplot3', - 'streamplotm', 'streamslice', 'subplot', 'subplots', 'suptitle', 'supxlabel', 'supylabel', - 'surf', 'taylor_diagram', 'text', 'text3', 'title', 'trisurf', 'twinx', 'twiny', 'violinplot', 'volumeplot', - 'weatherspec', 'xaxis', - 'xlabel', 'xlim', 'xreverse', 'xticks', 'yaxis', 'ylabel', 'ylim', 'yreverse', 'yticks', 'zaxis', 'zlabel', 'zlim', - 'zticks', - 'isinteractive' + 'axism', 'bar', 'bar3', 'barh', 'barbs', 'barbsm', 'bgcolor', 'box', 'boxplot', 'windrose', 'cla', + 'clabel', 'clc', 'clear', 'clf', 'cll', 'cloudspec', 'colorbar', 'contour', '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', + 'gifaddframe', 'gifanimation', 'giffinish', 'grid', 'gridshow', 'gridshowm', 'hist', 'imshow', + 'imshowm', 'isosurface', 'legend', 'left_title', 'lighting', 'loglog', 'makecolors', 'makelegend', + 'makesymbolspec', 'masklayer', 'material', 'mesh', 'meshc', 'model', 'particles', 'pcolor', 'pcolorm', + 'pie', 'plot', 'plot3', 'plotm', 'quiver', 'quiver3', 'quiverkey', 'quiverm', 'readlegend', + 'right_title', 'refresh', 'savefig', 'savefig_jpeg', 'scatter', 'scatter3', 'scatterm', 'semilogx', + 'semilogy', 'show', 'slice3', 'stationmodel', 'stem', 'stem3', 'step', 'streamplot', 'streamplot3', + 'streamplotm', 'streamslice', 'subplot', 'subplots', 'suptitle', 'supxlabel', 'supylabel', 'surf', + 'surfc', 'taylor_diagram', 'text', 'text3', 'title', 'trisurf', 'twinx', 'twiny', 'violinplot', + 'volumeplot', 'weatherspec', 'xaxis', 'xlabel', 'xlim', 'xreverse', 'xticks', 'yaxis', 'ylabel', + 'ylim', 'yreverse', 'yticks', 'zaxis', 'zlabel', 'zlim', 'zticks', 'isinteractive' ] @@ -1999,6 +1995,20 @@ def mesh(*args, **kwargs): return r +@_copy_docstring_and_deprecators(Axes3DGL.mesh) +def meshc(*args, **kwargs): + global g_axes + if g_axes is None: + g_axes = axes3d() + else: + if not isinstance(g_axes, Axes3D): + g_axes = axes3d() + + r = g_axes.meshc(*args, **kwargs) + draw_if_interactive() + return r + + @_copy_docstring_and_deprecators(Axes3D.surf) def surf(*args, **kwargs): global g_axes @@ -2013,6 +2023,20 @@ def surf(*args, **kwargs): return r +@_copy_docstring_and_deprecators(Axes3DGL.surfc) +def surfc(*args, **kwargs): + global g_axes + if g_axes is None: + g_axes = axes3d() + else: + if not isinstance(g_axes, Axes3D): + g_axes = axes3d() + + r = g_axes.surfc(*args, **kwargs) + draw_if_interactive() + return r + + @_copy_docstring_and_deprecators(Axes3DGL.trisurf) def trisurf(T, x, y, z, normal=None, **kwargs): global g_axes