5757 "digitize" ,
5858 "histogram" ,
5959 "histogram_bin_edges" ,
60- "histogram2d"
60+ "histogram2d" ,
6161 "histogramdd" ,
6262]
6363
@@ -139,6 +139,9 @@ def _is_finite(a):
139139 return numpy .isfinite (a )
140140
141141 if range is not None :
142+ if len (range ) != 2 :
143+ raise ValueError ("range argument must consist of 2 elements." )
144+
142145 first_edge , last_edge = range
143146 if first_edge > last_edge :
144147 raise ValueError ("max must be larger than min in range parameter." )
@@ -753,6 +756,7 @@ def histogram_bin_edges(a, bins=10, range=None, weights=None):
753756
754757
755758def histogram2d (x , y , bins = 10 , range = None , density = None , weights = None ):
759+ # pylint: disable=line-too-long
756760 """
757761 Compute the bi-dimensional histogram of two data samples.
758762
@@ -764,8 +768,10 @@ def histogram2d(x, y, bins=10, range=None, density=None, weights=None):
764768 y : {dpnp.ndarray, usm_ndarray} of shape (N,)
765769 An array containing the y coordinates of the points to be
766770 histogrammed.
767- bins : {int, list of dpnp.ndarray, list of usm_ndarray, sequence of scalars}, optional
768- The bin specification:
771+ bins : {int, list of dpnp.ndarray or usm_ndarray, sequence of scalars}, optional
772+ Histogram bins.
773+
774+ The bins specification:
769775
770776 * If int, the number of bins for the two dimensions (nx=ny=bins).
771777 * If array, the bin edges for the two dimensions
@@ -822,94 +828,73 @@ def histogram2d(x, y, bins=10, range=None, density=None, weights=None):
822828
823829 Examples
824830 --------
825- >>> import numpy as np
826- >>> from matplotlib.image import NonUniformImage
827- >>> import matplotlib.pyplot as plt
828-
829- Construct a 2-D histogram with variable bin width. First define the bin
830- edges:
831-
832- >>> xedges = [0, 1, 3, 5]
833- >>> yedges = [0, 2, 3, 4, 6]
834-
835- Next we create a histogram H with random bin content:
836-
837- >>> x = np.random.normal(2, 1, 100)
838- >>> y = np.random.normal(1, 1, 100)
839- >>> H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges))
840- >>> # Histogram does not follow Cartesian convention (see Notes),
841- >>> # therefore transpose H for visualization purposes.
842- >>> H = H.T
843-
844- :func:`imshow <matplotlib.pyplot.imshow>` can only display square bins:
845-
846- >>> fig = plt.figure(figsize=(7, 3))
847- >>> ax = fig.add_subplot(131, title='imshow: square bins')
848- >>> plt.imshow(H, interpolation='nearest', origin='lower',
849- ... extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]])
850- <matplotlib.image.AxesImage object at 0x...>
851-
852- :func:`pcolormesh <matplotlib.pyplot.pcolormesh>` can display actual edges:
853-
854- >>> ax = fig.add_subplot(132, title='pcolormesh: actual edges',
855- ... aspect='equal')
856- >>> X, Y = np.meshgrid(xedges, yedges)
857- >>> ax.pcolormesh(X, Y, H)
858- <matplotlib.collections.QuadMesh object at 0x...>
859-
860- :class:`NonUniformImage <matplotlib.image.NonUniformImage>` can be used to
861- display actual bin edges with interpolation:
862-
863- >>> ax = fig.add_subplot(133, title='NonUniformImage: interpolated',
864- ... aspect='equal', xlim=xedges[[0, -1]], ylim=yedges[[0, -1]])
865- >>> im = NonUniformImage(ax, interpolation='bilinear')
866- >>> xcenters = (xedges[:-1] + xedges[1:]) / 2
867- >>> ycenters = (yedges[:-1] + yedges[1:]) / 2
868- >>> im.set_data(xcenters, ycenters, H)
869- >>> ax.add_image(im)
870- >>> plt.show()
871-
872- It is also possible to construct a 2-D histogram without specifying bin
873- edges:
874-
875- >>> # Generate non-symmetric test data
876- >>> n = 10000
877- >>> x = np.linspace(1, 100, n)
878- >>> y = 2*np.log(x) + np.random.rand(n) - 0.5
879- >>> # Compute 2d histogram. Note the order of x/y and xedges/yedges
880- >>> H, yedges, xedges = np.histogram2d(y, x, bins=20)
881-
882- Now we can plot the histogram using
883- :func:`pcolormesh <matplotlib.pyplot.pcolormesh>`, and a
884- :func:`hexbin <matplotlib.pyplot.hexbin>` for comparison.
885-
886- >>> # Plot histogram using pcolormesh
887- >>> fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)
888- >>> ax1.pcolormesh(xedges, yedges, H, cmap='rainbow')
889- >>> ax1.plot(x, 2*np.log(x), 'k-')
890- >>> ax1.set_xlim(x.min(), x.max())
891- >>> ax1.set_ylim(y.min(), y.max())
892- >>> ax1.set_xlabel('x')
893- >>> ax1.set_ylabel('y')
894- >>> ax1.set_title('histogram2d')
895- >>> ax1.grid()
896-
897- >>> # Create hexbin plot for comparison
898- >>> ax2.hexbin(x, y, gridsize=20, cmap='rainbow')
899- >>> ax2.plot(x, 2*np.log(x), 'k-')
900- >>> ax2.set_title('hexbin')
901- >>> ax2.set_xlim(x.min(), x.max())
902- >>> ax2.set_xlabel('x')
903- >>> ax2.grid()
904-
905- >>> plt.show()
831+ >>> import dpnp as np
832+ >>> x = np.random.randn(20)
833+ >>> y = np.random.randn(20)
834+ >>> hist, edges_x, edges_y = np.histogram2d(x, y, bins=(4, 3))
835+ >>> hist
836+ [[1. 0. 0.]
837+ [0. 0. 0.]
838+ [5. 6. 4.]
839+ [1. 2. 1.]]
840+ >>> edges_x
841+ [-5.6575713 -3.5574734 -1.4573755 0.6427226 2.74282 ]
842+ >>> edges_y
843+ [-1.1889046 -0.07263839 1.0436279 2.159894 ]
906844 """
845+ # pylint: enable=line-too-long
846+
847+ dpnp .check_supported_arrays_type (x , y )
848+ if weights is not None :
849+ dpnp .check_supported_arrays_type (weights )
850+
851+ if x .ndim != 1 or y .ndim != 1 :
852+ raise ValueError (
853+ f"x and y must be 1-dimensional arrays."
854+ f"Got { x .ndim } and { y .ndim } respectively"
855+ )
907856
908857 if len (x ) != len (y ):
909- raise ValueError (f'x and y must have the same length. Got { len (x )} and { len (y )} respectively' )
858+ raise ValueError (
859+ f"x and y must have the same length."
860+ f"Got { len (x )} and { len (y )} respectively"
861+ )
862+
863+ usm_type , exec_q = get_usm_allocations ([x , y , bins , range , weights ])
864+ device = exec_q .sycl_device
865+
866+ sample_dtype = _result_type_for_device ([x .dtype , y .dtype ], device )
867+
868+ # Unlike histogramdd histogram2d accepts 1d bins and
869+ # apply it to both dimensions
870+ # at the same moment two elements bins should be interpreted as
871+ # number of bins in each dimension and array-like bins with one element
872+ # is not allowed
873+ if isinstance (bins , Iterable ) and len (bins ) > 2 :
874+ bins = [bins ] * 2
875+
876+ bins = _histdd_normalize_bins (bins , 2 )
877+ bins_dtypes = [sample_dtype ]
878+ bins_dtypes += [b .dtype for b in bins if hasattr (b , "dtype" )]
879+
880+ bins_dtype = _result_type_for_device (bins_dtypes , device )
881+ hist_dtype = _histdd_hist_dtype (exec_q , weights )
910882
883+ supported_types = statistics_ext .histogramdd_dtypes ()
884+
885+ sample_dtype , _ = _align_dtypes (
886+ sample_dtype , bins_dtype , hist_dtype , supported_types , device
887+ )
911888
912- hist , edges = histogramdd ([x , y ], bins , range , density , weights )
889+ sample = dpnp .empty_like (
890+ x , shape = x .shape + (2 ,), dtype = sample_dtype , usm_type = usm_type
891+ )
892+ sample [:, 0 ] = x
893+ sample [:, 1 ] = y
894+
895+ hist , edges = histogramdd (
896+ sample , bins = bins , range = range , density = density , weights = weights
897+ )
913898 return hist , edges [0 ], edges [1 ]
914899
915900
@@ -1080,7 +1065,7 @@ def _histdd_extract_arrays(sample, weights, bins):
10801065 return all_arrays
10811066
10821067
1083- def histogramdd (sample , bins = 10 , range = None , weights = None , density = False ):
1068+ def histogramdd (sample , bins = 10 , range = None , density = False , weights = None ):
10841069 """
10851070 Compute the multidimensional histogram of some data.
10861071
@@ -1155,7 +1140,7 @@ def histogramdd(sample, bins=10, range=None, weights=None, density=False):
11551140 elif sample .ndim > 2 :
11561141 raise ValueError ("sample must have no more than 2 dimensions" )
11571142
1158- ndim = sample .shape [1 ] if sample . size > 0 else 1
1143+ ndim = sample .shape [1 ]
11591144
11601145 _arrays = _histdd_extract_arrays (sample , weights , bins )
11611146 usm_type , queue = get_usm_allocations (_arrays )
0 commit comments