Changeset 3477478 in sasview for src/sas/plottools/plottables.py
- Timestamp:
- Mar 5, 2015 12:38:29 PM (9 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- b9dbd6b
- Parents:
- 2df0b74
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/plottools/plottables.py
r79492222 r3477478 45 45 import numpy 46 46 import sys 47 47 import logging 48 48 49 49 if 'any' not in dir(__builtins__): … … 53 53 return True 54 54 return False 55 55 56 56 def all(L): 57 57 for cond in L: … … 61 61 62 62 63 class Graph :63 class Graph(object): 64 64 """ 65 65 Generic plottables graph structure. 66 66 67 67 Plot styles are based on color/symbol lists. The user gets to select 68 68 the list of colors/symbols/sizes to choose from, not the application … … 77 77 the plottable objects themselves will need to provide the transformations. 78 78 Here are some examples from reflectometry: :: 79 79 80 80 independent: x -> f(x) 81 81 monitor scaling: y -> M*y … … 91 91 spin asymmetry: x -> x1, y -> (y1 - y2)/(y1 + y2) 92 92 vector net: x -> x1, y -> y1*cos(y2*pi/180) 93 93 94 94 Multiple transformations are possible, such as Q4 spin asymmetry 95 95 … … 122 122 Graphs need to be printable. A page layout program for entire plots 123 123 would be nice. 124 124 125 125 """ 126 126 def _xaxis_transformed(self, name, units): … … 134 134 self.prop["xlabel"] = name 135 135 self.prop["xunit"] = units 136 136 137 137 def _yaxis_transformed(self, name, units): 138 138 """ … … 145 145 self.prop["ylabel"] = name 146 146 self.prop["yunit"] = units 147 147 148 148 def xaxis(self, name, units): 149 149 """ … … 167 167 self.prop["ylabel_base"] = name 168 168 self.prop["yunit_base"] = units 169 169 170 170 def title(self, name): 171 171 """ … … 173 173 """ 174 174 self.prop["title"] = name 175 175 176 176 def get(self, key): 177 177 """ … … 216 216 """Detect if any graphed plottables have changed""" 217 217 return any([p.changed() for p in self.plottables]) 218 218 219 219 def get_range(self): 220 220 """ 221 221 Return the range of all displayed plottables 222 222 """ 223 min = None224 max = None223 min_value = None 224 max_value = None 225 225 for p in self.plottables: 226 226 if p.hidden == True: … … 228 228 if not p.x == None: 229 229 for x_i in p.x: 230 if min == None or x_i < min:231 min = x_i232 if max == None or x_i > max:233 max = x_i234 return min , max235 230 if min_value == None or x_i < min_value: 231 min_value = x_i 232 if max_value == None or x_i > max_value: 233 max_value = x_i 234 return min_value, max_value 235 236 236 def replace(self, plottable): 237 237 """Replace an existing plottable from the graph""" … … 252 252 del self.plottables[plottable] 253 253 self.color = len(self.plottables) 254 254 255 255 def reset_scale(self): 256 256 """ … … 268 268 "title": ""} 269 269 self.plottables = {} 270 270 271 271 def _make_labels(self): 272 272 """ … … 284 284 labels.update(c.labels(sets[c])) 285 285 return labels 286 286 287 287 def get_plottable(self, name): 288 288 """ … … 294 294 return item 295 295 return None 296 296 297 297 def returnPlottable(self): 298 298 """ … … 302 302 """ 303 303 return self.plottables 304 305 def render(self, plot):304 305 def render(self, plot): 306 306 """Redraw the graph""" 307 307 plot.connect.clearall() … … 312 312 if p.custom_color is not None: 313 313 p.render(plot, color=p.custom_color, symbol=0, 314 markersize=p.markersize, label=labels[p])314 markersize=p.markersize, label=labels[p]) 315 315 else: 316 316 p.render(plot, color=self.plottables[p], symbol=0, 317 markersize=p.markersize, label=labels[p])317 markersize=p.markersize, label=labels[p]) 318 318 plot.render() 319 319 320 320 def __init__(self, **kw): 321 321 self.reset() … … 328 328 # No need to inherit from this class, just need to provide 329 329 # the same methods. 330 class Transform :330 class Transform(object): 331 331 """ 332 332 Define a transform plugin to the plottable architecture. 333 333 334 334 Transforms operate on axes. The plottable defines the 335 335 set of transforms available for it, and the axes on which 336 336 they operate. These transforms can operate on the x axis 337 337 only, the y axis only or on the x and y axes together. 338 338 339 339 This infrastructure is not able to support transformations 340 340 such as log and polar plots as these require full control 341 341 over the drawing of axes and grids. 342 342 343 343 A transform has a number of attributes. 344 344 345 345 name 346 346 user visible name for the transform. This will 347 347 appear in the context menu for the axis and the transform 348 348 menu for the graph. 349 349 350 350 type 351 351 operational axis. This determines whether the … … 353 353 menus, or if it should appear in the context menu for 354 354 the graph. 355 355 356 356 inventory 357 (not implemented) 357 (not implemented) 358 358 a dictionary of user settable parameter names and 359 359 their associated types. These should appear as keyword 360 360 arguments to the transform call. For example, Fresnel 361 361 reflectivity requires the substrate density: 362 ``{ 'rho': type.Value(10e-6/units.angstrom**2) }`` 362 ``{ 'rho': type.Value(10e-6/units.angstrom**2) }`` 363 363 Supply reasonable defaults in the callback so that 364 364 limited plotting clients work even though they cannot 365 365 set the inventory. 366 366 367 367 """ 368 368 def __call__(self, plottable, **kwargs): … … 375 375 plottable should store the underlying data but set 376 376 the standard x,dx,y,dy,z,dz attributes appropriately. 377 377 378 378 If the call raises a NotImplemented error the dataline 379 379 will not be plotted. The associated string will usually … … 381 381 The application may or may not display the message to the 382 382 user, along with an indication of which plottable was at fault. 383 383 384 384 """ 385 385 raise NotImplemented, "Not a valid transform" … … 428 428 name = None 429 429 # Data 430 x 431 y 430 x = None 431 y = None 432 432 dx = None 433 433 dy = None … … 438 438 custom_color = None 439 439 markersize = 5 # default marker size is 'size 5' 440 440 441 441 def __init__(self): 442 442 self.view = View() … … 445 445 self._yaxis = "" 446 446 self._yunit = "" 447 447 448 448 def __setattr__(self, name, value): 449 449 """ … … 454 454 if name in ['x', 'y', 'dx', 'dy']: 455 455 self.reset_view() 456 # print "self.%s has been called" % name456 # print "self.%s has been called" % name 457 457 458 458 def set_data(self, x, y, dx=None, dy=None): … … 464 464 self.dx = dx 465 465 self.transformView() 466 466 467 467 def xaxis(self, name, units): 468 468 """ 469 469 Set the name and unit of x_axis 470 470 471 471 :param name: the name of x-axis 472 472 :param units: the units of x_axis 473 473 474 474 """ 475 475 self._xaxis = name … … 479 479 """ 480 480 Set the name and unit of y_axis 481 481 482 482 :param name: the name of y-axis 483 483 :param units: the units of y_axis 484 484 485 485 """ 486 486 self._yaxis = name 487 487 self._yunit = units 488 488 489 489 def get_xaxis(self): 490 490 """Return the units and name of x-axis""" 491 491 return self._xaxis, self._xunit 492 492 493 493 def get_yaxis(self): 494 494 """ Return the units and name of y- axis""" … … 500 500 Construct a set of unique labels for a collection of plottables of 501 501 the same type. 502 502 503 503 Returns a map from plottable to name. 504 504 505 505 """ 506 506 n = len(collection) 507 map= {}507 label_dict = {} 508 508 if n > 0: 509 509 basename = str(cls).split('.')[-1] 510 510 if n == 1: 511 map[collection[0]] = basename511 label_dict[collection[0]] = basename 512 512 else: 513 513 for i in xrange(len(collection)): 514 map[collection[i]] = "%s %d" % (basename, i)515 return map516 517 # #Use the following if @classmethod doesn't work514 label_dict[collection[i]] = "%s %d" % (basename, i) 515 return label_dict 516 517 # #Use the following if @classmethod doesn't work 518 518 # labels = classmethod(labels) 519 519 def setLabel(self, labelx, labely): 520 520 """ 521 521 It takes a label of the x and y transformation and set View parameters 522 522 523 523 :param transx: The label of x transformation is sent by Properties Dialog 524 524 :param transy: The label of y transformation is sent Properties Dialog 525 525 526 526 """ 527 527 self.view.xLabel = labelx 528 528 self.view.yLabel = labely 529 529 530 530 def set_View(self, x, y): 531 531 """Load View""" … … 533 533 self.y = y 534 534 self.reset_view() 535 535 536 536 def reset_view(self): 537 537 """Reload view with new value to plot""" … … 541 541 self.view.DXreel = self.view.dx 542 542 self.view.DYreel = self.view.dy 543 543 544 544 def render(self, plot): 545 545 """ 546 546 The base class makes sure the correct units are being used for 547 547 subsequent plottable. 548 548 549 549 For now it is assumed that the graphs are commensurate, and if you 550 put a Qx object on a Temperature graph then you had better hope 550 put a Qx object on a Temperature graph then you had better hope 551 551 that it makes sense. 552 552 553 553 """ 554 554 plot.xaxis(self._xaxis, self._xunit) 555 555 plot.yaxis(self._yaxis, self._yunit) 556 556 557 557 def is_empty(self): 558 558 """ … … 563 563 return True 564 564 return False 565 565 566 566 def colors(self): 567 567 """Return the number of colors need to render the object""" 568 568 return 1 569 569 570 570 def transformView(self): 571 571 """ … … 573 573 """ 574 574 self.view.transform(self.x, self.y, self.dx, self.dy) 575 575 576 576 def returnValuesOfView(self): 577 577 """ … … 579 579 """ 580 580 return self.view.returnXview() 581 581 582 582 def check_data_PlottableX(self): 583 583 """ … … 586 586 """ 587 587 self.view.check_data_logX() 588 588 589 589 def check_data_PlottableY(self): 590 590 """ 591 Since no transformation is made for log10(y), check that 591 Since no transformation is made for log10(y), check that 592 592 no negative values is plot in log scale 593 593 """ 594 594 self.view.check_data_logY() 595 595 596 596 def transformX(self, transx, transdx): 597 597 """ 598 598 Receive pointers to function that transform x and dx 599 599 and set corresponding View pointers 600 600 601 601 :param transx: pointer to function that transforms x 602 602 :param transdx: pointer to function that transforms dx 603 603 604 604 """ 605 605 self.view.setTransformX(transx, transdx) 606 606 607 607 def transformY(self, transy, transdy): 608 608 """ 609 609 Receive pointers to function that transform y and dy 610 610 and set corresponding View pointers 611 611 612 612 :param transy: pointer to function that transforms y 613 613 :param transdy: pointer to function that transforms dy 614 614 615 615 """ 616 616 self.view.setTransformY(transy, transdy) 617 617 618 618 def onReset(self): 619 619 """ … … 621 621 """ 622 622 self.view.onResetView() 623 623 624 624 def onFitRange(self, xmin=None, xmax=None): 625 625 """ 626 626 It limits View data range to plot from min to max 627 627 628 628 :param xmin: the minimum value of x to plot. 629 629 :param xmax: the maximum value of x to plot 630 630 631 631 """ 632 632 self.view.onFitRangeView(xmin, xmax) 633 634 635 class View :633 634 635 class View(object): 636 636 """ 637 637 Representation of the data that might include a transformation … … 672 672 :param dx: array of errors values on x 673 673 :param dy: array of error values on y 674 674 675 675 """ 676 676 # Sanity check … … 678 678 has_err_x = not (dx == None or len(dx) == 0) 679 679 has_err_y = not (dy == None or len(dy) == 0) 680 680 681 681 if(x != None) and (y != None): 682 682 if not dx == None and not len(dx) == 0 and not len(x) == len(dx): … … 689 689 msg += "and x are not of the same length" 690 690 raise ValueError, msg 691 691 692 692 if not dy == None and not len(dy) == 0 and not len(y) == len(dy): 693 693 msg = "Plottable.View: Given y and dy are not of the same " … … 750 750 self.DXreel = self.dx 751 751 self.DYreel = self.dy 752 752 753 753 def onResetView(self): 754 754 """ … … 760 760 self.dx = self.DXreel 761 761 self.dy = self.DYreel 762 762 763 763 def setTransformX(self, funcx, funcdx): 764 764 """ 765 765 Receive pointers to function that transform x and dx 766 766 and set corresponding View pointers 767 767 768 768 :param transx: pointer to function that transforms x 769 769 :param transdx: pointer to function that transforms dx … … 771 771 self.funcx = funcx 772 772 self.funcdx = funcdx 773 773 774 774 def setTransformY(self, funcy, funcdy): 775 775 """ 776 776 Receive pointers to function that transform y and dy 777 777 and set corresponding View pointers 778 778 779 779 :param transx: pointer to function that transforms y 780 780 :param transdx: pointer to function that transforms dy … … 782 782 self.funcy = funcy 783 783 self.funcdy = funcdy 784 784 785 785 def returnXview(self): 786 786 """ … … 788 788 """ 789 789 return self.x, self.y, self.dx, self.dy 790 790 791 791 def check_data_logX(self): 792 792 """ … … 805 805 for i in range(len(self.x)): 806 806 try: 807 if (self.x[i] > 0):807 if self.x[i] > 0: 808 808 tempx.append(self.x[i]) 809 809 tempdx.append(self.dx[i]) … … 811 811 tempdy.append(self.dy[i]) 812 812 except: 813 print "check_data_logX: skipping point x %g" % self.x[i] 814 print sys.exc_value 815 pass 813 logging.error("check_data_logX: skipping point x %g", self.x[i]) 814 logging.error(sys.exc_value) 816 815 self.x = tempx 817 816 self.y = tempy 818 817 self.dx = tempdx 819 818 self.dy = tempdy 820 819 821 820 def check_data_logY(self): 822 821 """ 823 822 Remove negative value in y vector 824 823 to avoid plotting negative value of Log10 825 824 826 825 """ 827 826 tempx = [] … … 833 832 if self.dy == None: 834 833 self.dy = numpy.zeros(len(self.y)) 835 if (self.yLabel == "log10(y)"):834 if self.yLabel == "log10(y)": 836 835 for i in range(len(self.x)): 837 836 try: 838 if (self.y[i] > 0):837 if self.y[i] > 0: 839 838 tempx.append(self.x[i]) 840 839 tempdx.append(self.dx[i]) … … 842 841 tempdy.append(self.dy[i]) 843 842 except: 844 print "check_data_logY: skipping point %g" % self.y[i]845 print sys.exc_value846 pass 843 logging.error("check_data_logY: skipping point %g", self.y[i]) 844 logging.error(sys.exc_value) 845 847 846 self.x = tempx 848 847 self.y = tempy 849 848 self.dx = tempdx 850 849 self.dy = tempdy 851 850 852 851 def onFitRangeView(self, xmin=None, xmax=None): 853 852 """ 854 853 It limits View data range to plot from min to max 855 854 856 855 :param xmin: the minimum value of x to plot. 857 856 :param xmax: the maximum value of x to plot 858 857 859 858 """ 860 859 tempx = [] … … 866 865 if self.dy == None: 867 866 self.dy = numpy.zeros(len(self.y)) 868 if (xmin != None) and (xmax != None):867 if xmin != None and xmax != None: 869 868 for i in range(len(self.x)): 870 if (self.x[i] >= xmin) and (self.x[i] <= xmax):869 if self.x[i] >= xmin and self.x[i] <= xmax: 871 870 tempx.append(self.x[i]) 872 871 tempdx.append(self.dx[i]) … … 878 877 self.dy = tempdy 879 878 880 879 881 880 class Data2D(Plottable): 882 881 """ … … 884 883 """ 885 884 def __init__(self, image=None, qx_data=None, qy_data=None, 886 887 885 err_image=None, xmin=None, xmax=None, ymin=None, 886 ymax=None, zmin=None, zmax=None): 888 887 """ 889 888 Draw image … … 898 897 self.source = None 899 898 self.detector = [] 900 901 # # Units for Q-values899 900 # # Units for Q-values 902 901 self.xy_unit = 'A^{-1}' 903 # # Units for I(Q) values902 # # Units for I(Q) values 904 903 self.z_unit = 'cm^{-1}' 905 904 self._zaxis = '' … … 910 909 self._yaxis = '\\rm{Q_{y}}' 911 910 self._yunit = 'A^{-1}' 912 913 # ## might remove that later914 # # Vector of Q-values at the center of each bin in x911 912 # ## might remove that later 913 # # Vector of Q-values at the center of each bin in x 915 914 self.x_bins = [] 916 # # Vector of Q-values at the center of each bin in y915 # # Vector of Q-values at the center of each bin in y 917 916 self.y_bins = [] 918 919 # x and y boundaries917 918 # x and y boundaries 920 919 self.xmin = xmin 921 920 self.xmax = xmax 922 921 self.ymin = ymin 923 922 self.ymax = ymax 924 923 925 924 self.zmin = zmin 926 925 self.zmax = zmax 927 926 self.id = None 928 927 929 928 def xaxis(self, label, unit): 930 929 """ 931 930 set x-axis 932 931 933 932 :param label: x-axis label 934 933 :param unit: x-axis unit 935 934 936 935 """ 937 936 self._xaxis = label 938 937 self._xunit = unit 939 938 940 939 def yaxis(self, label, unit): 941 940 """ 942 941 set y-axis 943 942 944 943 :param label: y-axis label 945 944 :param unit: y-axis unit 946 945 947 946 """ 948 947 self._yaxis = label 949 948 self._yunit = unit 950 949 951 950 def zaxis(self, label, unit): 952 951 """ 953 952 set z-axis 954 953 955 954 :param label: z-axis label 956 955 :param unit: z-axis unit 957 956 958 957 """ 959 958 self._zaxis = label 960 959 self._zunit = unit 961 960 962 961 def setValues(self, datainfo=None): 963 962 """ 964 963 Use datainfo object to initialize data2D 965 964 966 965 :param datainfo: object 967 966 968 967 """ 969 968 self.image = copy.deepcopy(datainfo.data) … … 971 970 self.qy_data = copy.deepcopy(datainfo.qy_data) 972 971 self.err_image = copy.deepcopy(datainfo.err_data) 973 972 974 973 self.xy_unit = datainfo.Q_unit 975 974 self.z_unit = datainfo.I_unit 976 975 self._zaxis = datainfo._zaxis 977 976 978 977 self.xaxis(datainfo._xunit, datainfo._xaxis) 979 978 self.yaxis(datainfo._yunit, datainfo._yaxis) 980 # x and y boundaries979 # x and y boundaries 981 980 self.xmin = datainfo.xmin 982 981 self.xmax = datainfo.xmax 983 982 self.ymin = datainfo.ymin 984 983 self.ymax = datainfo.ymax 985 # # Vector of Q-values at the center of each bin in x984 # # Vector of Q-values at the center of each bin in x 986 985 self.x_bins = datainfo.x_bins 987 # # Vector of Q-values at the center of each bin in y986 # # Vector of Q-values at the center of each bin in y 988 987 self.y_bins = datainfo.y_bins 989 988 990 989 def set_zrange(self, zmin=None, zmax=None): 991 990 """ … … 996 995 else: 997 996 raise "zmin is greater or equal to zmax " 998 997 999 998 def render(self, plot, **kw): 1000 999 """ 1001 1000 Renders the plottable on the graph 1002 1001 1003 1002 """ 1004 1003 plot.image(self.data, self.qx_data, self.qy_data, 1005 1004 self.xmin, self.xmax, self.ymin, 1006 1005 self.ymax, self.zmin, self.zmax, **kw) 1007 1006 1008 1007 def changed(self): 1009 1008 """ 1010 1009 """ 1011 1010 return False 1012 1011 1013 1012 @classmethod 1014 1013 def labels(cls, collection): 1015 1014 """Build a label mostly unique within a collection""" 1016 map= {}1015 label_dict = {} 1017 1016 for item in collection: 1018 #map[item] = label(item, collection)1019 #map[item] = r"$\rm{%s}$" % item.name1020 1017 if item.label == "Data2D": 1021 1018 item.label = item.name 1022 map[item] = item.label1023 return map1019 label_dict[item] = item.label 1020 return label_dict 1024 1021 1025 1022 … … 1028 1025 Data plottable: scatter plot of x,y with errors in x and y. 1029 1026 """ 1030 1027 1031 1028 def __init__(self, x, y, dx=None, dy=None): 1032 1029 """ … … 1056 1053 self.zorder = 1 1057 1054 self.hide_error = False 1058 1055 1059 1056 def render(self, plot, **kw): 1060 1057 """ … … 1068 1065 plot.interactive_points(self.view.x, self.view.y, 1069 1066 dx=self.view.dx, dy=self.view.dy, 1070 name=self.name, zorder=self.zorder, **kw)1067 name=self.name, zorder=self.zorder, **kw) 1071 1068 else: 1072 kw['id'] = 1069 kw['id'] = self.id 1073 1070 kw['hide_error'] = self.hide_error 1074 1071 kw['symbol'] = self.symbol … … 1076 1073 kw['markersize'] = self.markersize 1077 1074 plot.points(self.view.x, self.view.y, dx=self.view.dx, 1078 dy=self.view.dy, zorder=self.zorder,1079 marker=self.symbollist[self.symbol], **kw)1080 1075 dy=self.view.dy, zorder=self.zorder, 1076 marker=self.symbollist[self.symbol], **kw) 1077 1081 1078 def changed(self): 1082 1079 return False … … 1085 1082 def labels(cls, collection): 1086 1083 """Build a label mostly unique within a collection""" 1087 map= {}1084 label_dict = {} 1088 1085 for item in collection: 1089 #map[item] = label(item, collection)1090 #map[item] = r"$\rm{%s}$" % item.name1091 1086 if item.label == "data": 1092 1087 item.label = item.name 1093 map[item] = item.label1094 return map1095 1096 1088 label_dict[item] = item.label 1089 return label_dict 1090 1091 1097 1092 class Theory1D(Plottable): 1098 1093 """ 1099 1094 Theory plottable: line plot of x,y with confidence interval y. 1100 1101 1095 """ 1102 1096 def __init__(self, x, y, dy=None): … … 1105 1099 Confidence intervals in x are given by dx[i] or by (xlo[i],xhi[i]) 1106 1100 if the limits are asymmetric. 1107 1101 1108 1102 The title is the name that will show up on the legend. 1109 1103 """ 1110 1104 Plottable.__init__(self) 1111 msg = "Theory1D is no longer supported, please use Data1D and change" 1112 msg += " symbol.\n" 1105 msg = "Theory1D is no longer supported, please use Data1D and change symbol.\n" 1113 1106 raise DeprecationWarning, msg 1114 self.name = "theory" 1115 self.label = "theory" 1116 self.x = x 1117 self.y = y 1118 self.dy = dy 1119 self.xaxis('', '') 1120 self.yaxis('', '') 1121 self.view = View(self.x, self.y, None, self.dy) 1122 self.symbol = 0 1123 self.id = None 1124 self.zorder = 10 1125 1126 def render(self, plot, **kw): 1127 """ 1128 """ 1129 if self.interactive == True: 1130 kw['id'] = self.id 1131 plot.interactive_curve(self.view.x, self.view.y, 1132 dy=self.view.dy, 1133 name=self.name, zorder=self.zorder, **kw) 1134 else: 1135 kw['id'] = self.id 1136 plot.curve(self.view.x, self.view.y, dy=self.view.dy, 1137 zorder=self.zorder, **kw) 1138 1139 def changed(self): 1140 return False 1141 1142 @classmethod 1143 def labels(cls, collection): 1144 """Build a label mostly unique within a collection""" 1145 map = {} 1146 for item in collection: 1147 if item.label == "theory": 1148 item.label = item.name 1149 map[item] = item.label 1150 return map 1151 1152 1107 1153 1108 class Fit1D(Plottable): 1154 1109 """ … … 1159 1114 1160 1115 The color of the data and theory will be shared. 1161 1116 1162 1117 """ 1163 1118 def __init__(self, data=None, theory=None): … … 1194 1149 self.xpos = xpos 1195 1150 self.ypos = ypos 1196 1151 1197 1152 def render(self, plot, **kw): 1198 1153 """ … … 1206 1161 self.text, 1207 1162 label=self.name, 1208 transform=xcoords, 1209 ) 1210 1163 transform=xcoords) 1164 1211 1165 def setText(self, text): 1212 1166 """Set the text string.""" … … 1230 1184 """ 1231 1185 self.ypos = y 1232 1186 1233 1187 1234 1188 # --------------------------------------------------------------- … … 1244 1198 Plottable.__init__(self) 1245 1199 self.name = "chisq" 1246 #super( Chisq, self).__init__(None, None, None, None)1247 1200 self._chisq = chisq 1248 1201 self.xpos = 0.5 1249 1202 self.ypos = 0.9 1250 1203 1251 1204 def render(self, plot, **kw): 1252 1205 """ … … 1260 1213 1261 1214 xcoords = transforms.blended_transform_factory(plot.subplot.transAxes, 1262 plot.subplot.transAxes)1215 plot.subplot.transAxes) 1263 1216 plot.subplot.text(self.xpos, 1264 1217 self.ypos, 1265 1218 chisqTxt, label='chisq', 1266 transform=xcoords ,)1267 1219 transform=xcoords) 1220 1268 1221 def setChisq(self, chisq): 1269 1222 """ … … 1277 1230 def sample_graph(): 1278 1231 import numpy as nx 1279 1232 1280 1233 # Construct a simple graph 1281 1234 if False: 1282 x = nx.array([1, 2,3,4,5,6], 'd')1283 y = nx.array([4, 5,6,5,4,5], 'd')1235 x = nx.array([1, 2, 3, 4, 5, 6], 'd') 1236 y = nx.array([4, 5, 6, 5, 4, 5], 'd') 1284 1237 dy = nx.array([0.2, 0.3, 0.1, 0.2, 0.9, 0.3]) 1285 1238 else: … … 1300 1253 import wx 1301 1254 from pylab_plottables import Plotter 1302 # from mplplotter import Plotter1255 # from mplplotter import Plotter 1303 1256 1304 1257 # Make a frame to show it … … 1310 1263 # render the graph to the pylab plotter 1311 1264 graph.render(plotter) 1312 1313 class GraphUpdate :1265 1266 class GraphUpdate(object): 1314 1267 callnum = 0 1315 1268 1316 1269 def __init__(self, graph, plotter): 1317 1270 self.graph, self.plotter = graph, plotter 1318 1271 1319 1272 def __call__(self): 1320 1273 if self.graph.changed(): … … 1322 1275 return True 1323 1276 return False 1324 1277 1325 1278 def onIdle(self, event): 1326 1279 self.callnum = self.callnum + 1 1327 if self.__call__(): 1280 if self.__call__(): 1328 1281 pass # event.RequestMore() 1329 1282 update = GraphUpdate(graph, plotter)
Note: See TracChangeset
for help on using the changeset viewer.