@@ -670,17 +670,29 @@ def plot(self, xs, ys, *args, **kwargs):
670
670
Other arguments are passed on to
671
671
:func:`~matplotlib.axes.Axes.plot`
672
672
'''
673
-
673
+ # FIXME: This argument parsing might be better handled
674
+ # when we set later versions of python for
675
+ # minimum requirements. Currently at 2.4.
676
+ # Note that some of the reason for the current difficulty
677
+ # is caused by the fact that we want to insert a new
678
+ # (semi-optional) positional argument 'Z' right before
679
+ # many other traditional positional arguments occur
680
+ # such as the color, linestyle and/or marker.
674
681
had_data = self .has_data ()
675
682
zs = kwargs .pop ('zs' , 0 )
676
683
zdir = kwargs .pop ('zdir' , 'z' )
677
684
678
685
argsi = 0
679
686
# First argument is array of zs
680
687
if len (args ) > 0 and cbook .iterable (args [0 ]) and \
681
- len (xs ) == len (args [0 ]) and cbook .is_scalar (args [0 ][0 ]):
682
- zs = args [argsi ]
683
- argsi += 1
688
+ len (xs ) == len (args [0 ]) :
689
+ # So, we know that it is an array with
690
+ # first dimension the same as xs.
691
+ # Next, check to see if the data contained
692
+ # therein (if any) is scalar (and not another array).
693
+ if len (args [0 ]) == 0 or cbook .is_scalar (args [0 ][0 ]) :
694
+ zs = args [argsi ]
695
+ argsi += 1
684
696
685
697
# First argument is z value
686
698
elif len (args ) > 0 and cbook .is_scalar (args [0 ]):
@@ -860,7 +872,7 @@ def _shade_colors(self, color, normals):
860
872
colors = (0.5 + norm (shade )[:, np .newaxis ] * 0.5 ) * color
861
873
colors [:, 3 ] = alpha
862
874
else :
863
- colors = color .copy ()
875
+ colors = np . asanyarray ( color ) .copy ()
864
876
865
877
return colors
866
878
@@ -892,12 +904,37 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs):
892
904
cstride = kwargs .pop ("cstride" , 1 )
893
905
894
906
had_data = self .has_data ()
907
+ Z = np .atleast_2d (Z )
908
+ # FIXME: Support masked arrays
909
+ X = np .asarray (X )
910
+ Y = np .asarray (Y )
895
911
rows , cols = Z .shape
896
-
912
+ # Force X and Y to take the same shape.
913
+ # If they can not be fitted to that shape,
914
+ # then an exception is automatically thrown.
915
+ X .shape = (rows , cols )
916
+ Y .shape = (rows , cols )
917
+
918
+ # We want two sets of lines, one running along the "rows" of
919
+ # Z and another set of lines running along the "columns" of Z.
920
+ # This transpose will make it easy to obtain the columns.
897
921
tX , tY , tZ = np .transpose (X ), np .transpose (Y ), np .transpose (Z )
898
922
899
- rii = [i for i in range (0 , rows , rstride )]+ [rows - 1 ]
900
- cii = [i for i in range (0 , cols , cstride )]+ [cols - 1 ]
923
+ rii = range (0 , rows , rstride )
924
+ cii = range (0 , cols , cstride )
925
+
926
+ # Add the last index only if needed
927
+ if rows > 0 and rii [- 1 ] != (rows - 1 ) :
928
+ rii += [rows - 1 ]
929
+ if cols > 0 and cii [- 1 ] != (cols - 1 ) :
930
+ cii += [cols - 1 ]
931
+
932
+ # If the inputs were empty, then just
933
+ # reset everything.
934
+ if Z .size == 0 :
935
+ rii = []
936
+ cii = []
937
+
901
938
xlines = [X [i ] for i in rii ]
902
939
ylines = [Y [i ] for i in rii ]
903
940
zlines = [Z [i ] for i in rii ]
@@ -1133,16 +1170,21 @@ def add_collection3d(self, col, zs=0, zdir='z'):
1133
1170
- LineColleciton
1134
1171
- PatchCollection
1135
1172
'''
1173
+ zvals = np .atleast_1d (zs )
1174
+ if len (zvals ) > 0 :
1175
+ zsortval = min (zvals )
1176
+ else :
1177
+ zsortval = 0 # FIXME: Fairly arbitrary. Is there a better value?
1136
1178
1137
1179
if type (col ) is collections .PolyCollection :
1138
1180
art3d .poly_collection_2d_to_3d (col , zs = zs , zdir = zdir )
1139
- col .set_sort_zpos (min ( zs ) )
1181
+ col .set_sort_zpos (zsortval )
1140
1182
elif type (col ) is collections .LineCollection :
1141
1183
art3d .line_collection_2d_to_3d (col , zs = zs , zdir = zdir )
1142
- col .set_sort_zpos (min ( zs ) )
1184
+ col .set_sort_zpos (zsortval )
1143
1185
elif type (col ) is collections .PatchCollection :
1144
1186
art3d .patch_collection_2d_to_3d (col , zs = zs , zdir = zdir )
1145
- col .set_sort_zpos (min ( zs ) )
1187
+ col .set_sort_zpos (zsortval )
1146
1188
1147
1189
Axes .add_collection (self , col )
1148
1190
@@ -1251,7 +1293,14 @@ def bar(self, left, height, zs=0, zdir='z', *args, **kwargs):
1251
1293
if 'alpha' in kwargs :
1252
1294
p .set_alpha (kwargs ['alpha' ])
1253
1295
1254
- xs , ys = zip (* verts )
1296
+ if len (verts ) > 0 :
1297
+ # the following has to be skipped if verts is empty
1298
+ # NOTE: Bugs could still occur if len(verts) > 0,
1299
+ # but the "2nd dimension" is empty.
1300
+ xs , ys = zip (* verts )
1301
+ else :
1302
+ xs , ys = [], []
1303
+
1255
1304
xs , ys , verts_zs = art3d .juggle_axes (xs , ys , verts_zs , zdir )
1256
1305
self .auto_scale_xyz (xs , ys , verts_zs , had_data )
1257
1306
@@ -1317,6 +1366,7 @@ def bar3d(self, x, y, z, dx, dy, dz, color='b',
1317
1366
if len (x ) != len (y ) or len (x ) != len (z ):
1318
1367
warnings .warn ('x, y, and z must be the same length.' )
1319
1368
1369
+ # FIXME: This is archaic and could be done much better.
1320
1370
minx , miny , minz = 1e20 , 1e20 , 1e20
1321
1371
maxx , maxy , maxz = - 1e20 , - 1e20 , - 1e20
1322
1372
0 commit comments