import matplotlib.pyplot as plt plt.rcParams['text.usetex'] = True plt.rcParams['font.family'] = 'computer modern roman' plt.rcParams['mathtext.fontset'] = 'cm' plt.rcParams['mathtext.default'] = 'regular' plt.rcParams['svg.fonttype'] = 'path' plt.rc('text.latex', preamble=r'\usepackage{amsmath}') # Settings: fs_chart = 70 fs_lines = 75 fs_legend = 40 show_figs = True grid_props = dict(left=0, right=1, top=1, bottom=0) fig_props = { 'facecolor': 'none', 'edgecolor': 'none', 'frameon': False, } ax_props = { 'facecolor': 'none', 'frame_on': False, } text_props = { 'color': 'k', 'x': 0.5, 'y': 0.5, 'ha': 'center', 'va': 'center', } # Targets: texts = { # CIRCUIT ELEMENTS: # 'filt': (r'$x_{\text{filt}}$', fs_chart, (3, 3)), # 'env': (r'$x_{\text{env}}$', fs_chart, (3, 3)), # 'db': (r'$x_{\text{dB}}$', fs_chart, (3, 3)), # 'envdb': (r'$\begin{array}{c}x_{\text{env}}\\x_{\text{dB}}\end{array}$', fs_chart, (3, 3)), # 'adapt': (r'$x_{\text{adapt}}$', fs_chart, (3, 3)), # 'conv1': (r'$c_1$', fs_chart, (3, 3)), # 'conv2': (r'$c_2$', fs_chart, (3, 3)), # 'conv3': (r'$c_3$', fs_chart, (3, 3)), # 'bi1': (r'$b_{1, \Theta}$', fs_chart, (3, 3)), # 'bi2': (r'$b_{2, \Theta}$', fs_chart, (3, 3)), # 'bi3': (r'$b_{3, \Theta}$', fs_chart, (3, 3)), # 'feat1': (r'$f_{1, \Theta}$', fs_chart, (3, 3)), # 'feat2': (r'$f_{2, \Theta}$', fs_chart, (3, 3)), # 'feat3': (r'$f_{3, \Theta}$', fs_chart, (3, 3)), # 'out': (r'$\hat{y}$', fs_chart, (3, 3)), # CIRCUIT OPERATIONS: 'rectlp': (r'$\lvert\cdot\lvert,h_{\text{LP}}$', fs_lines, (3, 3)), 'log': (r'$\text{log}$', fs_lines, (3, 3)), 'rectlplog': (r'$\begin{array}{c}||,h_{\text{LP}}\\\text{log}\end{array}$', fs_lines, (3, 3)), 'k1': (r'$k_1$', fs_lines, (3, 3)), 'k2': (r'$k_2$', fs_lines, (3, 3)), 'k3': (r'$k_3$', fs_lines, (3, 3)), 'bp': (r'$h_{\text{BP}}$', fs_lines, (3, 3)), 'lp': (r'$h_{\text{LP}}$', fs_lines, (3, 3)), 'hp': (r'$h_{\text{HP}}$', fs_lines, (3, 3)), 'theta1': (r'$\Theta_1$', fs_lines, (3, 3)), 'theta2': (r'$\Theta_2$', fs_lines, (3, 3)), 'theta3': (r'$\Theta_3$', fs_lines, (3, 3)), 'w1': (r'$\omega_1$', fs_lines, (3, 3)), 'w2': (r'$\omega_2$', fs_lines, (3, 3)), 'w3': (r'$\omega_3$', fs_lines, (3, 3)), 'thresh1': (r'$H(c_1-\Theta_1)$', fs_lines, (3, 3)), 'thresh2': (r'$H(c_2-\Theta_2)$', fs_lines, (3, 3)), 'thresh3': (r'$H(c_3-\Theta_3)$', fs_lines, (3, 3)), # LEGEND ELEMENTS: # 'tympanum': ('Tympanal\nMembrane', fs_legend, (3, 3)), # 'receptors': ('Receptor\nNeuron\nPopulation', fs_legend, (3, 3)), # 'interneurons': ('Local\nInterneuron\nPopulation', fs_legend, (3, 3)), # 'ascending': ('Individual\nAscending\nNeurons', fs_legend, (3, 3)), # 'threshold': ('Threshold\nNonlinearity', fs_legend, (3, 3)), # 'integration': ('Temporal\nAveraging', fs_legend, (3, 3)), # 'brain': ('Weighting\nand\nReadout', fs_legend, (3, 3)), } # Save each target string: for name, (text, fs, size) in texts.items(): fig, ax = plt.subplots(figsize=size, gridspec_kw=grid_props, **fig_props) ax.set(**ax_props) ax.axis('off') ax.text(s=text, fontsize=fs, **text_props) fig.savefig(f'../figures/{name}_text.svg', dpi=300, bbox_inches='tight', pad_inches=0) if show_figs: plt.show() plt.close(fig) # def text_box(ax, text, xy, width, height, transform=None, # ha='center', va='center', **kwargs): # """ Maximizes fontsize of text to fit into a given bounding box. # Calculated fontsize depends on the aspect ratio of the bounding box, # the aspect ratio and alignment of the text, and the resolution and size # of the underlying figure. Text is not updated when resizing the figure. # Parameters # ---------- # ax : matplotlib axes object # Target subplot to annotate the text. # text : str # Text to fit into the specified bounding box under the given alignments. # xy : tuple of floats or ints (2,) # Text position in the coordinate system specified by transform. # width : float or int # Rectangle width in the coordinate system specified by transform. # height : float or int # Rectangle height in the coordinate system specified by transform. # transform : matplotlib transform, optional # Underlying coordinate system of the bounding box. Determines the # interpretation of xy, width, and height. Falls back to data coordinates # if unspecified. The default is None. # ha : str, optional # Horizontal alignment of bounding box and text relative to the given xy. # The default is 'center'. # va : str, optional # Vertical alignment of bounding box and text relative to the given xy. # The default is 'center'. # **kwargs : dict, optional # Additional keyword arguments passed to ax.annotate() for specifying # different font properties of the returned text object. # Returns # ------- # t : matplotlib text object # Annotated text object with adjusted fontsize to fit the bounding box. # """ # # Input interpretation: # if transform is None: # transform = ax.transData # fig = ax.get_figure() # x, y = xy # # Alignment-specific anchor points: # x_align1, x_align2 = { # 'center': (x - width / 2, x + width / 2), # 'left': (x, x + width), # 'right': (x - width, x), # }[ha] # y_align1, y_align2 = { # 'center': (y - height / 2, y + height / 2), # 'bottom': (y, y + height), # 'top': (y - height, y), # }[va] # # Anchor points in pixel: # left_corner = transform.transform((x_align1, y_align1)) # right_corner = transform.transform((x_align2, y_align2)) # # Bounding rectangle size in pixel: # pixel_width = right_corner[0] - left_corner[0] # pixel_height = right_corner[1] - left_corner[1] # # Adjust fontsize to box height (inch): # dpi = fig.dpi # rect_height = pixel_height / dpi # fs_initial = rect_height * 72 # # Plot first draft of the text: # t = ax.annotate(text, xy, ha=ha, va=va, xycoords=transform, **kwargs) # t.set_fontsize(fs_initial) # # Adjust fontsize to box width (inch): # bbox = t.get_window_extent(fig.canvas.get_renderer()) # fs_adjusted = fs_initial * pixel_width / bbox.width # t.set_fontsize(fs_adjusted) # return t # def text_graph(text, save_str=None, size=None, ax=None, show=False, # close=False, **kwargs): # """ Turns entire subplot into a text box that displays the given text. # Fontsize is maximized to fit the available bounding box. Text is always # centered in the subplot. Meant for creating scalable text elements that # comply with the style of other plot elements, especially for posters. # Parameters # ---------- # text : str # Text to be displayed. Can be multiline. Text fontsize is maximized by # text_box() to fit a bounding box that covers the entire axes area. # save_str : str, optional # If specified, saves the underlying figure under the given path. For # best results, use a vector format such as .svg). The default is None. # size : tuple of floats or ints (2,), optional # If specified, creates a new figure with given size in inches and a # single subplot. Indirectly controls the aspect ratio of the text box. # Must be specified if ax is None. The default is None. # ax : matplotlib axes object, optional # If specified, the target subplot to turn into a text box. Can be used # to set more properties such as the background color of the text box. # Must be specified if size is None. The default is None. # show : bool, optional # If True, displays the figure before returning. Else, returns without # showing the figure. The default is False. # **kwargs : dict, optional # Keyword arguments passed to text_box() and further to ax.annotate() for # specifying additional font properties of the displayed text. # Raises # ------ # ValueError # Breaks if neither size nor ax is specified to define a target subplot. # """ # # Input interpretation: # if size is not None: # fig, ax = plt.subplots(figsize=size) # elif ax is not None: # fig = ax.get_figure() # else: # raise ValueError('Either size or ax must be specified.') # # Turn drawable area of axes into a single text box: # text_box(ax, text, (0.5, 0.5), 1, 1, ax.transAxes, **kwargs) # # Hide other axes elements: # ax.xaxis.set_visible(False) # ax.yaxis.set_visible(False) # ax.spines[:].set_visible(False) # # Return options: # if save_str is not None: # fig.savefig(save_str, bbox_inches='tight') # if show: # plt.show() # return None