Ticket #3806: trac_3806-2.patch
| File trac_3806-2.patch, 16.5 KB (added by mhansen, 5 years ago) |
|---|
-
sage/plot/plot.py
# HG changeset patch # User Mike Hansen <mhansen@gmail.com> # Date 1218484321 25200 # Node ID 56a0f17397ce6adcf8fbf7fc622e7acf2419cd77 # Parent f203f4d382fdb2511e6880fabab51397bfe4e430 More improvements to plot.py. diff -r f203f4d382fd -r 56a0f17397ce sage/plot/plot.py
a b 990 990 angle -- 991 991 options -- dictionary of options 992 992 """ 993 xmin = point[0] - 2*r994 xmax = point[0] + 2*r995 ymin = point[1] - 2*r996 ymax = point[1] + 2*r993 xmin = point[0] - r 994 xmax = point[0] + r 995 ymin = point[1] - r 996 ymax = point[1] + r 997 997 self.__objects.append(GraphicPrimitive_Disk(point, r, angle, options)) 998 998 self._extend_axes(xmin, xmax, ymin, ymax) 999 999 … … 1009 1009 options -- dictionary of options 1010 1010 """ 1011 1011 self.__objects.append(GraphicPrimitive_Line(xdata, ydata, options)) 1012 try: 1013 self._extend_axes(min(xdata), max(xdata), min(ydata), max(ydata)) 1014 except ValueError: 1015 pass 1012 self._extend_axes(*minmax_data(xdata, ydata)) 1013 1016 1014 1017 1015 def _matrix_plot(self, xy_data_array, xrange, yrange, options): 1018 1016 """ … … 1059 1057 options -- dictionary of options 1060 1058 """ 1061 1059 self.__objects.append(GraphicPrimitive_Point(xdata, ydata, options)) 1062 try: 1063 self._extend_axes(min(xdata), max(xdata), min(ydata), max(ydata)) 1064 except ValueError: 1065 pass 1060 self._extend_axes(*minmax_data(xdata, ydata)) 1066 1061 1067 1062 def _polygon(self, xdata, ydata, options): 1068 1063 """ … … 1076 1071 options -- dictionary of options 1077 1072 """ 1078 1073 self.__objects.append(GraphicPrimitive_Polygon(xdata, ydata, options)) 1079 try: 1080 self._extend_axes(min(xdata), max(xdata), min(ydata), max(ydata)) 1081 except ValueError: 1082 pass 1074 self._extend_axes(*minmax_data(xdata, ydata)) 1083 1075 1084 1076 def _text(self, string, point, options): 1085 1077 """ … … 1683 1675 p.set_facecolor(c) 1684 1676 subplot.add_patch(p) 1685 1677 1678 1686 1679 #TODO: make bar_chart more general 1687 1680 class GraphicPrimitive_BarChart(GraphicPrimitive): 1688 1681 """ … … 2634 2627 ymin = float(minpoint[1]) 2635 2628 xmax = float(maxpoint[0]) 2636 2629 ymax = float(maxpoint[1]) 2637 return self._from_xdata_ydata(xmin, ymin, xmax, ymax, options=options) 2630 2631 g = Graphics(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 2632 g._arrow(xmin, ymin, xmax, ymax, options=options) 2633 return g 2638 2634 2639 2635 def _reset(self): 2640 2636 self.options={'width':0.02,'rgbcolor':(0, 0, 1)} … … 2648 2644 type arrow? for help and examples 2649 2645 """ 2650 2646 return "type arrow? for help and examples" 2651 2652 def _from_xdata_ydata(self, xmin, ymin, xmax, ymax, options):2653 g = Graphics(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)2654 g._arrow(xmin, ymin, xmax, ymax, options=options)2655 return g2656 2647 2657 2648 #an unique arrow instance 2658 2649 arrow = ArrowFactory() … … 2691 2682 yrange = (min(datalist), max(datalist)) 2692 2683 #bardata.append([ind, pnts, xrange, yrange]) 2693 2684 #cnt += 1 2694 return self._from_xdata_ydata(ind, datalist, xrange, yrange, options=options) 2695 2696 def _reset(self): 2697 self.options={'width':0.5,'rgbcolor':(0, 0, 1)} 2698 2699 def __repr__(self): 2700 """ 2701 Returns a string representation of this BarChartFactory object. 2702 2703 TESTS: 2704 sage: bar_chart 2705 type bar_chart? for help and examples 2706 """ 2707 return "type bar_chart? for help and examples" 2708 2709 def _from_xdata_ydata(self, ind, datalist, xrange, yrange, options): 2685 2710 2686 g = Graphics() 2711 2687 #TODO: improve below for multiple data sets! 2712 2688 #cnt = 1 … … 2718 2694 g._bar_chart(ind, datalist, xrange, yrange, options=options) 2719 2695 return g 2720 2696 2697 def _reset(self): 2698 self.options={'width':0.5,'rgbcolor':(0, 0, 1)} 2699 2700 def __repr__(self): 2701 """ 2702 Returns a string representation of this BarChartFactory object. 2703 2704 TESTS: 2705 sage: bar_chart 2706 type bar_chart? for help and examples 2707 """ 2708 return "type bar_chart? for help and examples" 2709 2721 2710 #an unique bar_chart instance 2722 2711 bar_chart = BarChartFactory() 2723 2712 … … 2758 2747 ... ocur = (rnext-r)-ocur 2759 2748 ... 2760 2749 sage: g.show(xmin=-(paths+1)^2, xmax=(paths+1)^2, ymin=-(paths+1)^2, ymax=(paths+1)^2, figsize=[6,6]) 2750 2751 TESTS: 2752 We test to make sure the x/y min/max data is set correctly. 2753 sage: p = circle((3, 3), 1) 2754 sage: p.xmin() 2755 2.0 2756 sage: p.ymin() 2757 2.0 2761 2758 """ 2762 2759 def __call__(self, point, radius, **kwds): 2763 2760 options = dict(self.options) 2764 2761 for k, v in kwds.iteritems(): 2765 2762 options[k] = v 2766 return self._from_xdata_ydata((float(point[0]), float(point[1])), 2767 float(radius), options=options) 2763 2764 r = float(radius) 2765 point = (float(point[0]), float(point[1])) 2766 g = Graphics(xmin=point[0]-r, xmax=point[0]+r, ymin=point[1]-r, ymax=point[1]+r) 2767 g._circle(point[0], point[1], r, options) 2768 return g 2768 2769 2769 2770 def _reset(self): 2770 2771 self.options={'alpha':1,'fill':False,'thickness':1,'rgbcolor':(0, 0, 1)} … … 2778 2779 type circle? for help and examples 2779 2780 """ 2780 2781 return "type circle? for help and examples" 2781 2782 def _from_xdata_ydata(self, point, r, options):2783 g = Graphics()2784 g._circle(float(point[0]), float(point[1]), float(r), options)2785 return g2786 2782 2787 2783 2788 2784 #an unique circle instance … … 2851 2847 sage: contour_plot(f, (-2, 2), (-2, 2), contours=(0.1, 1.0, 1.2, 1.4), cmap='hsv') 2852 2848 sage: contour_plot(f, (-2, 2), (-2, 2), contours=(1.0,), fill=False) 2853 2849 2850 2851 TESTS: 2852 We test to make sure that the x/y min/max data is set correctly. 2853 sage: p = contour_plot(f, (3, 6), (3, 6)) 2854 sage: p.xmin() 2855 3.0 2856 sage: p.ymin() 2857 3.0 2854 2858 """ 2855 2859 def __call__(self, f, xrange, yrange, **kwds): 2856 2860 options = dict(self.options) … … 2862 2866 xy_data_array = [[g(x, y) for x in \ 2863 2867 sage.misc.misc.xsrange(xrange[0], xrange[1], xstep)] 2864 2868 for y in sage.misc.misc.xsrange(yrange[0], yrange[1], ystep)] 2865 return self._from_xdata_ydata(xy_data_array, xrange, yrange, options=options) 2869 2870 g = Graphics(xmin=float(xrange[0]), xmax=float(xrange[1]), ymin=float(yrange[0]), ymax=float(yrange[1])) 2871 g._contour_plot(xy_data_array, xrange, yrange, options) 2872 return g 2866 2873 2867 2874 def _reset(self): 2868 2875 self.options={'plot_points':25, 'fill':True, 'cmap':'gray', 'contours':None} … … 2876 2883 type contour_plot? for help and examples 2877 2884 """ 2878 2885 return "type contour_plot? for help and examples" 2879 2880 def _from_xdata_ydata(self, xy_data_array, xrange, yrange, options): 2881 g = Graphics() 2882 g._contour_plot(xy_data_array, xrange, yrange, options) 2883 return g 2886 2884 2887 2885 2888 #unique contour_plot instance 2886 2889 contour_plot = ContourPlotFactory() … … 3074 3077 100.0 3075 3078 sage: l.xmax() 3076 3079 120.0 3077 3078 3080 """ 3079 3081 if coerce: 3080 3082 xdata, ydata = self._coerce(xdata, ydata) 3081 3083 3082 g = Graphics( xmin=min(xdata), xmax=max(xdata), ymin=min(ydata), ymax=max(ydata))3084 g = Graphics(**minmax_data(xdata, ydata, dict=True)) 3083 3085 g._Graphics__objects.append(GraphicPrimitive_Line(xdata, ydata, options)) 3084 3086 return g 3085 3087 … … 3114 3116 3115 3117 Another random plot, but over GF(389): 3116 3118 sage: matrix_plot(random_matrix(GF(389), 10), cmap='Oranges') 3119 3117 3120 """ 3118 3121 def __call__(self, mat, **kwds): 3119 3122 from sage.matrix.all import is_Matrix … … 3130 3133 xrange = (0, len(mat[0])) 3131 3134 yrange = (0, len(mat)) 3132 3135 xy_data_array = [array(r, dtype=float) for r in mat] 3133 return self._from_xdata_ydata(xy_data_array, xrange, yrange, options=options) 3136 3137 g = Graphics() 3138 g._matrix_plot(xy_data_array, xrange, yrange, options) 3139 return g 3134 3140 3135 3141 def _reset(self): 3136 3142 self.options={'cmap':'gray'} … … 3145 3151 """ 3146 3152 return "type matrix_plot? for help and examples" 3147 3153 3148 def _from_xdata_ydata(self, xy_data_array, xrange, yrange, options):3149 g = Graphics()3150 g._matrix_plot(xy_data_array, xrange, yrange, options)3151 return g3152 3154 3153 3155 #unique matrix_plot instance 3154 3156 matrix_plot = MatrixPlotFactory() … … 3180 3182 3181 3183 3182 3184 TESTS: 3183 sage: plot_vector_field((lambda x,y: .01*x,x+y), (-10,10), (-10,10)) 3185 sage: p = plot_vector_field((lambda x,y: .01*x,x+y), (10,20), (10,20)) 3186 sage: p.xmin() 3187 10.0 3188 sage: p.ymin() 3189 10.0 3184 3190 3185 3191 """ 3186 3192 def __call__(self, (f, g), xrange, yrange, **kwds): … … 3190 3196 z, xstep, ystep, xrange, yrange = setup_for_eval_on_grid([f,g], xrange, yrange, options['plot_points']) 3191 3197 f,g = z 3192 3198 3193 Lpx,Lpy,Lcx,Lcy = [],[],[],[]3199 xpos_array, ypos_array, xvec_array, yvec_array = [],[],[],[] 3194 3200 for x in sage.misc.misc.xsrange(xrange[0], xrange[1], xstep): 3195 3201 for y in sage.misc.misc.xsrange(yrange[0], yrange[1], ystep): 3196 Lpx.append(x) 3197 Lpy.append(y) 3198 Lcx.append(f(x,y)) 3199 Lcy.append(g(x,y)) 3200 return self._from_xdata_ydata(Lpx, Lpy, Lcx, Lcy, xrange, yrange, options=options) 3201 3202 def _reset(self): 3203 self.options={'plot_points':20, 'cmap':'gray'} 3204 3205 def _repr_(self): 3206 return "type plot_vector_field? for help and examples" 3207 3208 def _from_xdata_ydata(self, xpos_array, ypos_array, xvec_array, yvec_array, xrange, yrange, options): 3202 xpos_array.append(x) 3203 ypos_array.append(y) 3204 xvec_array.append(f(x,y)) 3205 yvec_array.append(g(x,y)) 3206 3209 3207 import numpy 3210 3208 xvec_array = numpy.array(xvec_array, dtype=float) 3211 3209 yvec_array = numpy.array(yvec_array, dtype=float) 3212 g = Graphics( )3210 g = Graphics(xmin=xrange[0], xmax=xrange[1], ymin=yrange[0], ymax=yrange[1]) 3213 3211 g._plot_field(xpos_array, ypos_array, xvec_array, yvec_array, xrange, yrange, options) 3214 3212 return g 3213 3214 def _reset(self): 3215 self.options={'plot_points':20, 'cmap':'gray'} 3216 3217 def _repr_(self): 3218 return "type plot_vector_field? for help and examples" 3215 3219 3216 3220 #unique plot_vector_field instance 3217 3221 plot_vector_field = PlotFieldFactory() … … 3234 3238 sage: P = tl+tr+bl+br 3235 3239 sage: P.show(figsize=(4,4),xmin=-2,xmax=2,ymin=-2,ymax=2) 3236 3240 3241 TESTS: 3242 Check to make sure that the x/y min/max data is correctly set. 3243 sage: d = disk((5,5), 1, (pi/2, pi), rgbcolor=(0,0,0)) 3244 sage: d.xmin() 3245 4.0 3246 sage: d.ymin() 3247 4.0 3248 sage: d.xmax() 3249 6.0 3237 3250 """ 3238 3251 def __call__(self, point, radius, angle, **kwds): 3239 3252 options = dict(self.options) 3240 3253 for k, v in kwds.iteritems(): 3241 3254 options[k] = v 3242 return self._from_xdata_ydata((float(point[0]), float(point[1])),float(radius), 3243 (float(angle[0]), float(angle[1])), options=options) 3255 3256 r = float(radius) 3257 point = (float(point[0]), float(point[1])) 3258 angle = (float(angle[0]), float(angle[1])) 3259 3260 xmin = point[0] - r 3261 xmax = point[0] + r 3262 ymin = point[1] - r 3263 ymax = point[1] + r 3264 g = Graphics(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 3265 g._disk(point, r, angle, options) 3266 return g 3244 3267 3245 3268 def _reset(self): 3246 3269 self.options={'alpha':1,'fill':True,'rgbcolor':(0,0,1),'thickness':0} … … 3254 3277 type disk? for help and examples 3255 3278 """ 3256 3279 return "type disk? for help and examples" 3257 3258 def _from_xdata_ydata(self, point, r, angle, options):3259 g = Graphics()3260 g._disk(point, r, angle, options)3261 return g3262 3280 3263 3281 #an unique disk instance 3264 3282 disk = DiskFactory() … … 3277 3295 Here are some random larger red points, given as a list of tuples 3278 3296 sage: point(((0.5, 0.5), (1, 2), (0.5, 0.9), (-1, -1)), rgbcolor=hue(1), pointsize=30) 3279 3297 3298 TESTS: 3299 We check to make sure that the x/y min/max data is set correctly. 3300 sage: p = point((3, 3), rgbcolor=hue(0.75)) 3301 sage: p.xmin() 3302 3.0 3303 sage: p.ymin() 3304 3.0 3305 3280 3306 """ 3281 3307 def _reset(self): 3282 3308 self.options = {'alpha':1,'pointsize':10,'faceted':False,'rgbcolor':(0,0,1)} … … 3294 3320 def _from_xdata_ydata(self, xdata, ydata, coerce, options): 3295 3321 if coerce: 3296 3322 xdata, ydata = self._coerce(xdata, ydata) 3297 g = Graphics( xmin=min(xdata), xmax=max(xdata), ymin=min(ydata), ymax=max(ydata))3323 g = Graphics(**minmax_data(xdata, ydata, dict=True)) 3298 3324 g._Graphics__objects.append(GraphicPrimitive_Point(xdata, ydata, options)) 3299 3325 return g 3300 3326 … … 3360 3386 sage: L = [[sin(pi*i/100)+sin(pi*i/50),-(1+cos(pi*i/100)+cos(pi*i/50))] for i in range(-100,100)] 3361 3387 sage: polygon(L, rgbcolor=(1,1/4,1/2)) 3362 3388 3389 TESTS: 3390 We check to make sure that the x/y min/max data is set correctly. 3391 sage: p = polygon([[1,2], [5,6], [5,0]], rgbcolor=(1,0,1)) 3392 sage: p.ymin() 3393 0.0 3394 sage: p.xmin() 3395 1.0 3396 3397 3363 3398 AUTHORS: 3364 3399 -- David Joyner (2006-04-14): the long list of examples above. 3365 3400 … … 3380 3415 def _from_xdata_ydata(self, xdata, ydata, coerce, options): 3381 3416 if coerce: 3382 3417 xdata, ydata = self._coerce(xdata, ydata) 3383 g = Graphics( )3418 g = Graphics(**minmax_data(xdata, ydata, dict=True)) 3384 3419 g._Graphics__objects.append(GraphicPrimitive_Polygon(xdata, ydata, options)) 3385 try:3386 g._extend_axes(min(xdata), max(xdata), min(ydata), max(ydata))3387 except ValueError:3388 pass3389 3420 return g 3390 3421 3391 3422 # unique polygon instance … … 3648 3679 3649 3680 try: 3650 3681 data[i] = (float(xi), float(f(xi))) 3651 except (ZeroDivisionError, TypeError, ValueError, OverflowError), msg:3682 except (ZeroDivisionError, TypeError, ValueError, OverflowError), msg: 3652 3683 sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, x),1) 3653 3684 exceptions += 1 3654 3685 exception_indices.append(i) 3686 3687 if str(data[i][1]) in ['nan', 'NaN']: 3688 sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, x),1) 3689 exceptions += 1 3690 exception_indices.append(i) 3691 3655 3692 data = [data[i] for i in range(len(data)) if i not in exception_indices] 3656 3693 3657 3694 # adaptive refinement … … 3836 3873 3837 3874 This gives all the random points joined in a purple line: 3838 3875 sage: list_plot(r, plotjoined=True, rgbcolor=(1,0,1)) 3876 3877 TESTS: 3878 We check to see that the x/y min/max data are set correctly. 3879 sage: p = list_plot([(100,100), (120, 120)]) 3880 sage: p.xmin() 3881 100.0 3882 sage: p.ymin() 3883 100.0 3884 3839 3885 """ 3840 3886 if not isinstance(data[0], (list, tuple)): 3841 3887 data = zip(range(len(data)),data) … … 4460 4506 g.append(fast_float(f, str(xvar), str(yvar))) 4461 4507 4462 4508 return g, xstep, ystep, xrange, yrange 4509 4510 4511 def minmax_data(xdata, ydata, dict=False): 4512 """ 4513 Returns the minimums and maximums of xdata and ydata. 4514 4515 If dict is False, then minmax_data returns the tuple 4516 (xmin, xmax, ymin, ymax); otherwise, it returns a dictionary 4517 whose keys are 'xmin', 'xmax', 'ymin', and 'ymax' and whose 4518 values are the corresponding values. 4519 4520 EXAMPLES: 4521 sage: from sage.plot.plot import minmax_data 4522 sage: minmax_data([], []) 4523 (-1, 1, -1, 1) 4524 sage: minmax_data([-1, 2], [4, -3]) 4525 (-1, 2, -3, 4) 4526 sage: d = minmax_data([-1, 2], [4, -3], dict=True) 4527 sage: list(sorted(d.items())) 4528 [('xmax', 2), ('xmin', -1), ('ymax', 4), ('ymin', -3)] 4529 4530 """ 4531 xmin = min(xdata) if len(xdata) > 0 else -1 4532 xmax = max(xdata) if len(xdata) > 0 else 1 4533 ymin = min(ydata) if len(ydata) > 0 else -1 4534 ymax = max(ydata) if len(ydata) > 0 else 1 4535 if dict: 4536 return {'xmin':xmin, 'xmax':xmax, 4537 'ymin':ymin, 'ymax':ymax} 4538 else: 4539 return xmin, xmax, ymin, ymax
