1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23   
 24  """Module containing the base class for the OpenDX space mapping classes.""" 
 25   
 26   
 27   
 28  from copy import deepcopy 
 29  from numpy import float64, array, zeros 
 30  from time import asctime, localtime 
 31   
 32   
 33  from lib.errors import RelaxError 
 34  from lib.io import open_write_file, write_data 
 35  from extern.numpy_future import percentile 
 36  from lib.software.opendx.files import write_config, write_general, write_point, write_program 
 37  from pipe_control import value 
 38  from specific_analyses.api import return_api 
 39   
 40   
 41 -def map(params=None, map_type='Iso3D', spin_id=None, inc=20, lower=None, upper=None, axis_incs=10, file_prefix="map", dir="dx", point=None, point_file="point", chi_surface=None, create_par_file=False): 
  42      """Map the space corresponding to the spin identifier and create the OpenDX files. 
 43   
 44      @keyword params:            The list of model parameters to map. 
 45      @type params:               list of str 
 46      @keyword map_type:          The type of map to create.  The available options are: 
 47                                      - 'Iso3D', a 3D isosurface visualisation of the space. 
 48      @type map_type:             str 
 49      @keyword spin_id:           The spin identification string. 
 50      @type spin_id:              str 
 51      @keyword inc:               The resolution of the plot.  This is the number of increments per dimension. 
 52      @type inc:                  int 
 53      @keyword lower:             The lower bounds of the space to map.  If supplied, this should be a list of floats, its length equal to the number of parameters in the model. 
 54      @type lower:                None or list of float 
 55      @keyword upper:             The upper bounds of the space to map.  If supplied, this should be a list of floats, its length equal to the number of parameters in the model. 
 56      @type upper:                None or list of float 
 57      @keyword axis_incs:         The number of tick marks to display in the OpenDX plot in each dimension. 
 58      @type axis_incs:            int 
 59      @keyword file_prefix:       The file prefix for all the created files. 
 60      @type file_prefix:          str 
 61      @keyword dir:               The directory to place the files into. 
 62      @type dir:                  str or None 
 63      @keyword point:             If supplied, a red sphere will be placed at these coordinates. 
 64      @type point:                None or list of float 
 65      @keyword point_file:        The file prefix for the point output files. 
 66      @type point_file:           str or None 
 67      @keyword create_par_file:   Whether to create a file with parameters and associated chi2 value. 
 68      @type create_par_file:      bool 
 69      """ 
 70   
 71       
 72      if inc <= 1: 
 73          raise RelaxError("The increment value needs to be greater than 1.") 
 74      if axis_incs <= 1: 
 75          raise RelaxError("The axis increment value needs to be greater than 1.") 
 76   
 77       
 78      if map_type.lower() == "iso3d": 
 79          if len(params) != 3: 
 80              raise RelaxError("The 3D isosurface map requires a 3 parameter model.") 
 81   
 82           
 83          Map(params, spin_id, inc, lower, upper, axis_incs, file_prefix, dir, point, point_file, chi_surface, create_par_file) 
 84      else: 
 85          raise RelaxError("The map type '" + map_type + "' is not supported.") 
  86   
 87   
 88   
 90      """The space mapping base class.""" 
 91   
 92 -    def __init__(self, params, spin_id, inc, lower, upper, axis_incs, file_prefix, dir, point, point_file, chi_surface, create_par_file): 
  93          """Map the space upon class instantiation.""" 
 94   
 95           
 96           
 97   
 98           
 99          self.params = params 
100          self.spin_id = spin_id 
101          self.n = len(params) 
102          self.inc = inc 
103          self.axis_incs = axis_incs 
104          self.file_prefix = file_prefix 
105          self.dir = dir 
106          self.point_file = point_file 
107   
108           
109          self.par_chi2_vals = [] 
110   
111           
112          self.api = return_api() 
113   
114           
115          if point != None: 
116               
117              point_list = [] 
118              if isinstance(point[0], float): 
119                  point_list.append(array(point, float64)) 
120                  self.point = point_list 
121                  self.num_points = 1 
122              else: 
123                  for i in range(len(point)): 
124                      point_list.append(array(point[i], float64)) 
125                  self.point = point_list 
126                  self.num_points = i + 1 
127          else: 
128              self.num_points = 0 
129   
130           
131          self.bounds = zeros((self.n, 2), float64) 
132          for i in range(self.n): 
133               
134              bounds = self.api.map_bounds(self.params[i], self.spin_id) 
135   
136               
137              if not bounds: 
138                  raise RelaxError("No bounds for the parameter " + repr(self.params[i]) + " could be determined.") 
139   
140               
141              self.bounds[i] = bounds 
142   
143           
144          if lower != None: 
145              self.bounds[:, 0] = array(lower, float64) 
146   
147           
148          if upper != None: 
149              self.bounds[:, 1] = array(upper, float64) 
150   
151           
152          self.step_size = zeros(self.n, float64) 
153          self.step_size = (self.bounds[:, 1] - self.bounds[:, 0]) / self.inc 
154   
155   
156           
157           
158   
159           
160          self.get_date() 
161   
162           
163          self.map_axes() 
164   
165           
166          self.create_map() 
167   
168           
169          if create_par_file: 
170              self.create_par_chi2(file_prefix=self.file_prefix, par_chi2_vals=self.par_chi2_vals) 
171   
172               
173              self.matplotlib_surface_plot() 
174   
175           
176          if self.num_points >= 1 and create_par_file: 
177               
178              par_chi2_vals = self.calc_point_par_chi2() 
179   
180               
181              self.create_par_chi2(file_prefix=self.point_file, par_chi2_vals=par_chi2_vals) 
182   
183           
184          if chi_surface == None: 
185              all_chi2 = array(self.all_chi, float64) 
186              innermost = percentile(all_chi2, 10) 
187              inner = percentile(all_chi2, 20) 
188              middle = percentile(all_chi2, 50) 
189              outer = percentile(all_chi2, 90) 
190              chi_surface = [innermost, inner, middle, outer] 
191   
192           
193          write_program(file_prefix=self.file_prefix, point_file=self.point_file, dir=self.dir, inc=self.inc, N=self.n, num_points=self.num_points, labels=self.labels, tick_locations=self.tick_locations, tick_values=self.tick_values, date=self.date, chi_surface = chi_surface) 
194   
195           
196          write_config(file_prefix=self.file_prefix, dir=self.dir, date=self.date) 
197   
198           
199          write_general(file_prefix=self.file_prefix, dir=self.dir, inc=self.inc) 
200   
201           
202          if self.num_points >= 1: 
203              write_point(file_prefix=self.point_file, dir=self.dir, inc=self.inc, point=self.point, num_points=self.num_points, bounds=self.bounds, N=self.n) 
 204   
205   
207          """Function for chi2 value for the points.""" 
208   
209           
210          print("\nCalculate chi2 value for the point parameters.") 
211   
212           
213          par_chi2_vals = [] 
214   
215           
216          for i in range(self.num_points): 
217              i_point = self.point[i] 
218   
219               
220              if self.spin_id: 
221                  value.set(val=i_point, param=self.params, spin_id=self.spin_id, force=True) 
222              else: 
223                  value.set(val=i_point, param=self.params, force=True) 
224   
225               
226              if self.spin_id: 
227                  self.api.calculate(spin_id=self.spin_id, verbosity=0) 
228              else: 
229                  self.api.calculate(verbosity=0) 
230   
231               
232              if self.spin_id: 
233                  k, n, chi2 = self.api.model_statistics(spin_id=self.spin_id) 
234              else: 
235                  k, n, chi2 = self.api.model_statistics(model_info=0) 
236   
237               
238              par_chi2_vals.append([i, i_point[0], i_point[1], i_point[2], chi2]) 
239   
240           
241          return par_chi2_vals 
 242   
243   
245          """Function for creating the map.""" 
246   
247           
248          print("\nCreating the map.") 
249   
250           
251          map_file = open_write_file(file_name=self.file_prefix, dir=self.dir, force=True) 
252   
253           
254          self.map_3D_text(map_file) 
255   
256           
257          map_file.close() 
 258   
259   
261          """Function for creating file with parameters and the chi2 value.""" 
262   
263           
264          print("\nCreating the file with parameters and the chi2 value.") 
265   
266           
267          par_file = open_write_file(file_name=file_prefix+'.par', dir=self.dir, force=True) 
268   
269           
270          par_chi2_vals_sort = deepcopy(par_chi2_vals) 
271   
272           
273          par_chi2_vals_sort.sort(key=lambda values: values[4]) 
274   
275           
276          data = [] 
277          for i, line in enumerate(par_chi2_vals): 
278              line_sort = par_chi2_vals_sort[i] 
279   
280               
281              line_str = ["%3.5f"%j for j in line] 
282              line_sort_str = ["%3.5f"%j for j in line_sort] 
283   
284               
285              line_str[0] = "%i" % line[0] 
286              line_sort_str[0] = "%i" % line_sort[0] 
287   
288               
289              data_list = line_str + line_sort_str 
290              data.append(data_list) 
291   
292           
293          headings = ['i'] + self.params + ['chi2'] 
294          headings += headings 
295   
296           
297          headings[5] = headings[5] + "_sort" 
298          headings[6] = headings[6] + "_sort" 
299          headings[7] = headings[7] + "_sort" 
300          headings[8] = headings[8] + "_sort" 
301          headings[9] = headings[9] + "_sort" 
302   
303           
304          write_data(out=par_file, headings=headings, data=data) 
305   
306           
307          par_file.close() 
 308   
309   
311          """Function for creating a date string.""" 
312   
313          self.date = asctime(localtime()) 
 314   
315   
316 -    def map_3D_text(self, map_file): 
 317          """Function for creating the text of a 3D map.""" 
318   
319           
320          values = zeros(3, float64) 
321          percent = 0.0 
322          percent_inc = 100.0 / (self.inc + 1.0)**(self.n - 1.0) 
323          print("%-10s%8.3f%-1s" % ("Progress:", percent, "%")) 
324   
325           
326          all_chi = [] 
327   
328           
329          unfix = False 
330          if hasattr(cdp, 'diff_tensor') and not cdp.diff_tensor.fixed: 
331              cdp.diff_tensor.fixed = True 
332              unfix = True 
333   
334           
335          values[0] = self.bounds[0, 0] 
336   
337           
338          counter = 0 
339   
340           
341          for i in range((self.inc + 1)): 
342               
343              values[1] = self.bounds[1, 0] 
344   
345               
346              for j in range((self.inc + 1)): 
347                   
348                  values[2] = self.bounds[2, 0] 
349   
350                   
351                  for k in range((self.inc + 1)): 
352                       
353                      if self.spin_id: 
354                          value.set(val=values, param=self.params, spin_id=self.spin_id, verbosity=0, force=True) 
355                      else: 
356                          value.set(val=values, param=self.params, verbosity=0, force=True) 
357   
358                       
359                      if self.spin_id: 
360                          self.api.calculate(spin_id=self.spin_id, verbosity=0) 
361                      else: 
362                          self.api.calculate(verbosity=0) 
363   
364                       
365                      if self.spin_id: 
366                          k, n, chi2 = self.api.model_statistics(spin_id=self.spin_id) 
367                      else: 
368                          k, n, chi2 = self.api.model_statistics(model_info=0) 
369   
370                       
371                      if chi2 > 1e20: 
372                          map_file.write("%30f\n" % 1e20) 
373                      else: 
374                          map_file.write("%30f\n" % chi2) 
375   
376                           
377                          all_chi.append(chi2) 
378   
379                       
380                      self.par_chi2_vals.append([counter, values[0], values[1], values[2], chi2]) 
381   
382                       
383                      counter += 1 
384   
385                       
386                      values[2] = values[2] + self.step_size[2] 
387   
388                   
389                  percent = percent + percent_inc 
390                  print("%-10s%8.3f%-8s%-8g" % ("Progress:", percent, "%,  " + repr(values) + ",  f(x): ", chi2)) 
391   
392                   
393                  values[1] = values[1] + self.step_size[1] 
394   
395               
396              values[0] = values[0] + self.step_size[0] 
397   
398           
399          if unfix: 
400              cdp.diff_tensor.fixed = False 
401   
402           
403          self.all_chi = all_chi 
 404   
406          """Function for creating labels, tick locations, and tick values for an OpenDX map.""" 
407   
408           
409          self.labels = "{" 
410          self.tick_locations = [] 
411          self.tick_values = [] 
412          loc_inc = float(self.inc) / float(self.axis_incs) 
413   
414           
415          for i in range(self.n): 
416               
417              factor = self.api.return_conversion_factor(self.params[i]) 
418   
419               
420              units = self.api.return_units(self.params[i]) 
421   
422               
423              if units: 
424                  self.labels = self.labels + "\"" + self.params[i] + " (" + units + ")\"" 
425              else: 
426                  self.labels = self.labels + "\"" + self.params[i] + "\"" 
427   
428              if i < self.n - 1: 
429                  self.labels = self.labels + " " 
430              else: 
431                  self.labels = self.labels + "}" 
432   
433               
434              vals = self.bounds[i, 0] / factor 
435              val_inc = (self.bounds[i, 1] - self.bounds[i, 0]) / (self.axis_incs * factor) 
436   
437              string = "" 
438              for j in range(self.axis_incs + 1): 
439                  string = string + "\"" + "%.2f" % vals + "\" " 
440                  vals = vals + val_inc 
441              self.tick_values.append("{" + string + "}") 
442   
443               
444              string = "" 
445              val = 0.0 
446              for j in range(self.axis_incs + 1): 
447                  string = string + " " + repr(val) 
448                  val = val + loc_inc 
449              self.tick_locations.append("{" + string + " }") 
 450   
451   
453          """Function to write matplotlib script to plot surfaces of parameters.""" 
454   
455           
456          mapfile_name = '"%s.par"' % self.file_prefix 
457   
458           
459          if self.point_file != None: 
460              pointfile_name = '"%s.par"' % self.point_file 
461          else: 
462              pointfile_name = "None" 
463   
464           
465          plot_file = open_write_file(file_name=self.file_prefix+'.py', dir=self.dir, force=True) 
466   
467          matplotlib_file = [ 
468              'from copy import deepcopy'+"\n", 
469              'import numpy as np'+"\n", 
470              'import scipy.interpolate'+"\n", 
471              'from numpy.ma import masked_where'+"\n", 
472              ''+"\n", 
473              'from mpl_toolkits.mplot3d import axes3d'+"\n", 
474              'import matplotlib.pyplot as plt'+"\n", 
475              'from matplotlib import cm'+"\n", 
476              ''+"\n", 
477              '# Open file and get header.'+"\n", 
478              'mapfile_name = %s'%mapfile_name+"\n", 
479              'pointfile_name = %s'%pointfile_name+"\n", 
480              ''+"\n", 
481              'mapfile = open(mapfile_name, "r")'+"\n", 
482              'lines = mapfile.readlines()'+"\n", 
483              'mapfile.close()'+"\n", 
484              'header = lines[0].split()[1:]'+"\n", 
485              ''+"\n", 
486              '# Prepare the dtype for reading file.'+"\n", 
487              'dtype_str = "i8,f8,f8,f8,f8,i8,f8,f8,f8,f8"'+"\n", 
488              ''+"\n", 
489              'print("Fileheader is: %s"%header)'+"\n", 
490              'print("Value types are: %s"%dtype_str)'+"\n", 
491              ''+"\n", 
492              '# Load the data.'+"\n", 
493              'data = np.genfromtxt(fname=mapfile_name, dtype=dtype_str, names=header)'+"\n", 
494              ''+"\n", 
495              '# Load the point data'+"\n", 
496              'if pointfile_name:'+"\n", 
497              '    # Load the point data.'+"\n", 
498              '    data_p = np.genfromtxt(fname=pointfile_name, dtype=dtype_str, names=header)'+"\n", 
499              '    '+"\n", 
500              ''+"\n", 
501              '# Define where to cut the data, as the minimum.'+"\n", 
502              'header_min = header[6:10]'+"\n", 
503              ''+"\n", 
504              '# Define to cut at min map point.'+"\n", 
505              'map_min_par0 = data[header_min[0]][0]'+"\n", 
506              'map_min_par1 = data[header_min[1]][0]'+"\n", 
507              'map_min_par2 = data[header_min[2]][0]'+"\n", 
508              'map_min_chi2 = data[header_min[3]][0]'+"\n", 
509              ''+"\n", 
510              '# Now get the headers for the data.'+"\n", 
511              'header_val = header[1:5]'+"\n", 
512              ''+"\n", 
513              '# Define which 2D maps to create, as a list of 2 parameters, and at which third parameter to cut the values.'+"\n", 
514              'maps_xy = [header_val[0], header_val[1], header_val[2], map_min_par2]'+"\n", 
515              'maps_xz = [header_val[0], header_val[2], header_val[1], map_min_par1]'+"\n", 
516              'maps_yz = [header_val[1], header_val[2], header_val[0], map_min_par0]'+"\n", 
517              ''+"\n", 
518              'maps = [maps_xy, maps_xz, maps_yz]'+"\n", 
519              ''+"\n", 
520              '# Nr of columns is number of maps.'+"\n", 
521              'nr_cols = 1'+"\n", 
522              '# Nr of rows, is 2, for 3d projection and imshow'+"\n", 
523              'nr_rows = 2'+"\n", 
524              ''+"\n", 
525              '# Loop over the maps:'+"\n", 
526              'for x_par, y_par, z_par, z_cut in maps:'+"\n", 
527              '    # Define figure'+"\n", 
528              '    fig = plt.figure()'+"\n", 
529              ''+"\n", 
530              '    # Define c_par'+"\n", 
531              '    c_par = header_val[3]'+"\n", 
532              ''+"\n", 
533              '    # Now get the values for the map.'+"\n", 
534              '    map_x = data[x_par]'+"\n", 
535              '    map_y = data[y_par]'+"\n", 
536              '    map_z = data[z_par]'+"\n", 
537              '    map_c = data[c_par]'+"\n", 
538              ''+"\n", 
539              '    # Now define which map to create.'+"\n", 
540              '    mask_xy = masked_where(map_z == z_cut, map_z)'+"\n", 
541              '    map_mask_x = map_x[mask_xy.mask]'+"\n", 
542              '    map_mask_y = map_y[mask_xy.mask]'+"\n", 
543              '    map_mask_c = map_c[mask_xy.mask]'+"\n", 
544              ''+"\n", 
545              '    # Define min and max values.'+"\n", 
546              '    map_mask_x_min = map_mask_x.min()'+"\n", 
547              '    map_mask_x_max = map_mask_x.max()'+"\n", 
548              '    map_mask_y_min = map_mask_y.min()'+"\n", 
549              '    map_mask_y_max = map_mask_y.max()'+"\n", 
550              '    map_mask_c_min = map_mask_c.min()'+"\n", 
551              '    map_mask_c_max = map_mask_c.max()'+"\n", 
552              ''+"\n", 
553              '    # Set up a regular grid of interpolation points'+"\n", 
554              '    int_points = 300'+"\n", 
555              '    xi, yi = np.linspace(map_mask_x_min, map_mask_x_max, int_points), np.linspace(map_mask_y_min, map_mask_y_max, int_points)'+"\n", 
556              '    xi, yi = np.meshgrid(xi, yi)'+"\n", 
557              ''+"\n", 
558              '    # Interpolate to create grid'+"\n", 
559              '    ci = scipy.interpolate.griddata((map_mask_x, map_mask_y), map_mask_c, (xi, yi), method="linear")'+"\n", 
560              ''+"\n", 
561              '    # Set which x, y, z to plot'+"\n", 
562              '    x_p = xi'+"\n", 
563              '    y_p = yi'+"\n", 
564              '    c_p = deepcopy(ci)'+"\n", 
565              ''+"\n", 
566              '    # Cut map at a certain height.'+"\n", 
567              '    # First get index os largest values'+"\n", 
568              '    #z_max = map_mask_c_max'+"\n", 
569              '    z_max = map_mask_c_min + 0.5*map_mask_c_min'+"\n", 
570              '    ci_mask = masked_where(ci >= z_max, ci)'+"\n", 
571              ''+"\n", 
572              '    # Replace with 0.0'+"\n", 
573              '    c_p[ci_mask.mask] = 0.0'+"\n", 
574              '    # Find new max'+"\n", 
575              '    new_max = np.max(c_p)'+"\n", 
576              ''+"\n", 
577              '    # Insert values in array.'+"\n", 
578              '    c_p[ci_mask.mask] = new_max'+"\n", 
579              ''+"\n", 
580              '    # Define min.'+"\n", 
581              '    z_min = map_mask_c_min - 0.5*map_mask_c_min'+"\n", 
582              ''+"\n", 
583              '    # Create figure and plot'+"\n", 
584              '    ax = fig.add_subplot(nr_rows, nr_cols, 1, projection="3d")'+"\n", 
585              '    ax.plot_surface(x_p, y_p, c_p, rstride=8, cstride=8, alpha=0.3)'+"\n", 
586              ''+"\n", 
587              '    # Possible add scatter points for map.'+"\n", 
588              '    #ax.scatter(map_x, map_y, map_c, c="b", marker="o", s=5)'+"\n", 
589              ''+"\n", 
590              '    # One could also make the mesh just from the values, but this require much memory.'+"\n", 
591              '    ##ax.scatter(x_p, y_p, c_p, c="y", marker="o", s=5)'+"\n", 
592              ''+"\n", 
593              '    # Add contour levels on sides.'+"\n", 
594              '    ax.contour(x_p, y_p, c_p, zdir="z", offset=z_min, cmap=cm.coolwarm)'+"\n", 
595              '    ax.contour(x_p, y_p, c_p, zdir="x", offset=map_mask_x_min, cmap=cm.coolwarm)'+"\n", 
596              '    ax.contour(x_p, y_p, c_p, zdir="y", offset=map_mask_y_min, cmap=cm.coolwarm)'+"\n", 
597              ''+"\n", 
598              '    # Add scatter values, for 5 lowest values.'+"\n", 
599              '    x_par_min = x_par + "_sort"'+"\n", 
600              '    y_par_min = y_par + "_sort"'+"\n", 
601              '    c_par_min = c_par + "_sort"'+"\n", 
602              '    mp_x = data[x_par_min][0:5]'+"\n", 
603              '    mp_y = data[y_par_min][0:5]'+"\n", 
604              '    mp_c = data[c_par_min][0:5]'+"\n", 
605              '    ax.scatter(mp_x[0], mp_y[0], mp_c[0], c="r", marker="o", s=200)'+"\n", 
606              '    ax.scatter(mp_x[1:], mp_y[1:], mp_c[1:], c="g", marker="o", s=100)'+"\n", 
607              ''+"\n", 
608              '    # Add points from file, as the closest point in map.'+"\n", 
609              '    if pointfile_name:'+"\n", 
610              '        if data_p[x_par].ndim == 0:'+"\n", 
611              '            points_x = np.asarray([data_p[x_par]])'+"\n", 
612              '            points_y = np.asarray([data_p[y_par]])'+"\n", 
613              '        else:'+"\n", 
614              '            points_x = data_p[x_par]'+"\n", 
615              '            points_y = data_p[y_par]'+"\n", 
616              ''+"\n", 
617              '        # Normalize, by division of largest number of map'+"\n", 
618              '        points_x_norm = points_x / map_mask_x_max'+"\n", 
619              '        points_y_norm = points_y / map_mask_y_max'+"\n", 
620              '        map_mask_x_norm = map_mask_x / map_mask_x_max'+"\n", 
621              '        map_mask_y_norm = map_mask_y / map_mask_y_max'+"\n", 
622              ''+"\n", 
623              '        p_x = []'+"\n", 
624              '        p_y = []'+"\n", 
625              '        p_c = []'+"\n", 
626              '        # Now calculate the Euclidean distance in the space, to find map point best represents the point.'+"\n", 
627              '        for i, point_x_norm in enumerate(points_x_norm):'+"\n", 
628              '            point_y_norm = points_y_norm[i]'+"\n", 
629              ''+"\n", 
630              '            # Get the distance.'+"\n", 
631              '            dist = np.sqrt( (map_mask_x_norm - point_x_norm)**2 + (map_mask_y_norm - point_y_norm)**2)'+"\n", 
632              ''+"\n", 
633              '            # Return the indices of the minimum values along an axis.'+"\n", 
634              '            min_index = np.argmin(dist)'+"\n", 
635              '            p_x.append(map_mask_x[min_index])'+"\n", 
636              '            p_y.append(map_mask_y[min_index])'+"\n", 
637              '            p_c.append(map_mask_c[min_index])'+"\n", 
638              ''+"\n", 
639              '        # Convert to numpy array'+"\n", 
640              '        p_x = np.asarray(p_x)'+"\n", 
641              '        p_y = np.asarray(p_y)'+"\n", 
642              '        p_c = np.asarray(p_c)'+"\n", 
643              ''+"\n", 
644              '        # Plot points'+"\n", 
645              '        ax.scatter(p_x, p_y, p_c, c="m", marker="o", s=50)'+"\n", 
646              ''+"\n", 
647              ''+"\n", 
648              '    # Set label'+"\n", 
649              '    ax.set_xlabel("%s"%x_par)'+"\n", 
650              '    ax.set_ylabel("%s"%y_par)'+"\n", 
651              '    ax.set_zlabel("%s"%c_par)'+"\n", 
652              ''+"\n", 
653              ''+"\n", 
654              '    # Set limits'+"\n", 
655              '    ax.set_zlim(z_min, z_max)'+"\n", 
656              ''+"\n", 
657              ''+"\n", 
658              '    # Create figure and plot'+"\n", 
659              '    ax = fig.add_subplot(nr_rows, nr_cols, 2)'+"\n", 
660              '    fig_imshow = ax.imshow(ci, vmin=map_mask_c_min, vmax=map_mask_c_max, origin="lower", extent=[map_mask_x_min, map_mask_x_max, map_mask_y_min, map_mask_y_max])'+"\n", 
661              ''+"\n", 
662              '    # Add scatter values, for 5 lowest values.'+"\n", 
663              '    ax.scatter(mp_x[0], mp_y[0], c=mp_c[0], marker="o", s=200)'+"\n", 
664              '    ax.scatter(mp_x[1:], mp_y[1:], c="g", marker="o", s=100)'+"\n", 
665              ''+"\n", 
666              '    # Also add point to this map.'+"\n", 
667              '    if pointfile_name:'+"\n", 
668              '        # Plot points'+"\n", 
669              '        ax.scatter(p_x, p_y, c="m", marker="o", s=50)'+"\n", 
670              ''+"\n", 
671              '    # Set label'+"\n", 
672              '    ax.set_xlabel("%s"%x_par)'+"\n", 
673              '    ax.set_ylabel("%s"%y_par)'+"\n", 
674              ''+"\n", 
675              '    # Add colorbar.'+"\n", 
676              '    fig.subplots_adjust(right=0.8)'+"\n", 
677              '    cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.3])'+"\n", 
678              '    fig.colorbar(fig_imshow, cax=cbar_ax)'+"\n", 
679              ''+"\n", 
680              '# Show plot.'+"\n", 
681              'plt.show()'+"\n", 
682              ''+"\n", 
683          ] 
684   
685           
686          for line in matplotlib_file: 
687              plot_file.write(line) 
688   
689           
690          plot_file.close() 
  691