Advertisement
OreganoHauch

plotIV function

Aug 20th, 2020
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.20 KB | None | 0 0
  1. def plotIV(coordinate=None, thinning=100, set_region=(0,999,0,999), showPosition=False, figsize=(30,15), savepng=False, dpi=None, annotations=False, data_processing=1, return_only=False):
  2.  
  3. start = time.time()
  4. # voltages
  5. voltages = [-1000, -500, -200, -100, 0, 100, 200, 500, 600]
  6. # scans (ordered by voltages)
  7. scans_ordered = [ 189, 188, 185, 183,181,182, 186, 187, 190]
  8.  
  9. current_mean = []
  10. current_array_list = []
  11.  
  12. # plot either with or without negative values and select if the solar cell channel should be selected for the current
  13. options_dic = {
  14. 1: (False, False, "Lock in R , ohne Negativwerte"),
  15. 2: (False, True, "Lock in R, mit Negativwerten"),
  16. 3: (True, False, "solar cell channel, ohne Negativwerte"),
  17. 4: (True, True, "solar cell channel, mit Negativwerten")
  18. }
  19. if not return_only:
  20. print(options_dic[data_processing][2])
  21. A = 2 # plot only from scan_ordered[A] to ...
  22. B = -2 # ... scan_ordered[B]
  23. for scan in scans_ordered[A:B]:
  24. positions = load_h5(scan, "positions")
  25. y_axis_h5 = positions["/data/encoder_fast/data"]
  26. z_axis_h5 = positions["/data/encoder_slow/data"]
  27. y_axis = np.array(y_axis_h5)
  28. z_axis = np.array(z_axis_h5)
  29. current = counts2amps(scan,solar_cell_channel_only=options_dic[data_processing][0], negative=options_dic[data_processing][1])
  30.  
  31. y_grid, z_grid, current_array = supergrid(y_axis,z_axis,current,1000)
  32.  
  33. shape = np.shape(current_array)
  34. if scan not in [178,181]:
  35. warp_matrix = ImageRegistrationDic[scan]
  36. current_array = cv2.warpAffine(current_array, warp_matrix, (shape[1], shape[0]), flags = cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP, borderValue = float("NaN")).astype(np.float32)
  37.  
  38. current_mean.append(np.mean(current))
  39.  
  40. current_array_list.append(current_array)
  41.  
  42. pixelplotting_array = np.stack(current_array_list)
  43.  
  44. if return_only:
  45. return current_array, pixelplotting_array
  46.  
  47. for i in range(len(current_mean)):
  48. print("Mean current for scan", str(scans_ordered[i+A]), "is {} nA.".format(str(round(current_mean[i],2))))
  49.  
  50. # the best looking fontsize is about half of the width of the figsize
  51. fontsize = figsize[0]//2
  52. fig = plt.figure(figsize=figsize)
  53. ax1 = fig.add_subplot(121)
  54. # y and z labels
  55. ax1.set_xlabel("Bias voltage [mV]", labelpad = 0, style = "italic", fontsize=9/5*fontsize)
  56. ax1.set_ylabel("Measured current at (y,z) position [nA]", labelpad = 0, style = "italic", fontsize=9/5*fontsize)
  57. plt.title("IV curve(s) for single pixel(s)", pad = 15, fontsize=round(9/5*fontsize))
  58. ax1.tick_params(labelsize=fontsize)
  59. ax1.set_xticks(voltages[A:B])
  60.  
  61. # allows to plot only a specific location on the y-z current array (else plot each 'thinning'-squared-th IV curve):
  62. if coordinate != None:
  63. ax1.plot(voltages[A:B], pixelplotting_array[:,coordinate[0],coordinate[1]], "-o", markersize=8, linewidth=0.2, color="blue")
  64.  
  65. # Create a set of inset Axes: these should fill the bounding box allocated to them.
  66. ax1_2 = plt.axes([0,0,1,1])
  67. # Manually set the position and relative size of the inset axes within ax1
  68. ip = InsetPosition(ax1, [0.2,0.2,0.3,0.3])
  69. ax1_2.set_axes_locator(ip)
  70. # ticks and ticklabels need to be shifted according to Image Registration
  71. scan = scans_ordered[B-1] # show the scan of the last IV curve point as an example
  72. IRS_y = ImageRegistrationDic[scan][0][2] # IRS = Image Registration Shift (in y or z)
  73. IRS_z = ImageRegistrationDic[scan][1][2]
  74. # individual ticks: it's an extrapolated plot from 201x201 to 1000x1000 pixels, but this corresponds to 10x10 micrometers on the solar cell
  75. ax1_2.xaxis.set_ticklabels([0,5,10],fontsize=round(4/5*fontsize))
  76. ax1_2.xaxis.set_ticks([0-IRS_y,500-IRS_y,999-IRS_y]) # if 1000 instead of 999 it won't display
  77. ax1_2.yaxis.set_ticklabels([0,5,10],fontsize=round(4/5*fontsize))
  78. ax1_2.yaxis.set_ticks([0-IRS_z,500-IRS_z,999-IRS_z])
  79. ax1_2.xaxis.set_minor_locator(AutoMinorLocator(5)) # 1 minor tick for each micrometer
  80. ax1_2.yaxis.set_minor_locator(AutoMinorLocator(5))
  81.  
  82. ax1_2.imshow(current_array, interpolation='nearest', cmap=cm.afmhot, origin='lower')
  83. ax1_2.plot([coordinate[0]],coordinate[1], "bo", markersize=4)
  84. # y and z labels
  85. ax1_2.set_xlabel("Position Y [μm]", labelpad = 0, style = "italic", fontsize=fontsize)
  86. ax1_2.set_ylabel("Position Z [μm]", labelpad = 0, style = "italic", fontsize=fontsize)
  87.  
  88. print("Number of NaN values on shown IV curve:", str(len(np.where(np.isnan(pixelplotting_array[:,coordinate[0],coordinate[1]])))))
  89.  
  90. if coordinate == None:
  91. countnumberlines = 0
  92. for y in np.linspace(set_region[0],set_region[1],1000/thinning,dtype=int):
  93. for z in np.linspace(set_region[2],set_region[3],1000/thinning,dtype=int):
  94. ax1.plot(voltages[A:B], pixelplotting_array[:,y,z], "-o", markersize=2, linewidth=0.2, color="blue")
  95. if showPosition:
  96. # Create a set of inset Axes: these should fill the bounding box allocated to them.
  97. ax1_2 = plt.axes([0,0,1,1])
  98. # Manually set the position and relative size of the inset axes within ax1
  99. ip = InsetPosition(ax1, [0.2,0.05,figsize[0]/120,figsize[0]/120])
  100. ax1_2.set_axes_locator(ip)
  101. # ticks and ticklabels need to be shifted according to Image Registration
  102. scan = scans_ordered[B-1] # show the scan of the last IV curve point as an example
  103. IRS_y = ImageRegistrationDic[scan][0][2] # IRS = Image Registration Shift (in y or z)
  104. IRS_z = ImageRegistrationDic[scan][1][2]
  105. # individual ticks: it's an extrapolated plot from 201x201 to 1000x1000 pixels, but this corresponds to 10x10 micrometers on the solar cell
  106. ax1_2.xaxis.set_ticklabels([0,5,10],fontsize=round(4/5*fontsize))
  107. ax1_2.xaxis.set_ticks([0-IRS_y,500-IRS_y,999-IRS_y]) # if 1000 instead of 999 it won't display
  108. ax1_2.yaxis.set_ticklabels([0,5,10],fontsize=round(4/5*fontsize))
  109. ax1_2.yaxis.set_ticks([0-IRS_z,500-IRS_z,999-IRS_z])
  110. ax1_2.xaxis.set_minor_locator(AutoMinorLocator(5)) # 1 minor tick for each micrometer
  111. ax1_2.yaxis.set_minor_locator(AutoMinorLocator(5))
  112.  
  113. ax1_2.imshow(current_array, interpolation='nearest', cmap=cm.afmhot, origin='lower')
  114. ax1_2.plot(y,z, "bo", markersize=4)
  115. # y and z labels
  116. ax1_2.set_xlabel("Position Y [μm]", labelpad = 0, style = "italic", fontsize=fontsize)
  117. ax1_2.set_ylabel("Position Z [μm]", labelpad = 0, style = "italic", fontsize=fontsize)
  118. countnumberlines += 1
  119. print("Number of IV curves shown in plot:", str(countnumberlines))
  120.  
  121. ax2 = fig.add_subplot(122)
  122. ax2.plot(voltages[A:B], current_mean, "-o")
  123. plt.title("Mean IV curve", pad = 15, fontsize=round(9/5*fontsize))
  124. ax2.tick_params(labelsize=fontsize)
  125. ax2.set_xticks(voltages[A:B])
  126. if annotations:
  127. for i in range(len(current_mean)):
  128. ax2.annotate("Scan " + str(scans_ordered[i+A]), xy=(voltages[i+A], current_mean[i]), xytext=(voltages[i+A], current_mean[i]+1.3), arrowprops=dict(facecolor='black', shrink=0.12, width=2, headwidth=8))
  129.  
  130. end = time.time()
  131. print("Plotting took {} seconds.".format(str(round(end-start,2))))
  132.  
  133. plt.show()
  134.  
  135. if savepng:
  136. from datetime import datetime
  137. now = datetime.now()
  138. dt_string = now.strftime("%d-%m-%Y_%H_%M_%S")
  139. if dpi is None:
  140. fig.savefig("savefig/IV_curve_" + dt_string + ".png", dpi=fig.dpi, bbox_inches="tight")
  141. else:
  142. fig.savefig("savefig/IV_curve_" + dt_string + ".png", dpi=dpi, bbox_inches="tight")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement