def text_width(s): fp = FontProperties(family='DejaVu Sans', size=11) w, h, d = TextToPath().get_text_width_height_descent(s, fp, False) return int(w + 1)
def __init__(self, ax, x, y, text): self._x = x self._y = y self.width = 0.5 self.height = 0.2 self.connector_radius = self.height / 10 self.picked_offset = (0,0) self.offsets = dict(u = self.height, d = 0, l = self.width / 2, r = -self.width / 2, c = 0) self.patch = mpl.patches.Rectangle((self.x - self.width / 2, self.y - self.height / 2), self.width, self.height, transform=ax.transData) # ------------------------------------------------------ x0, y0 = self.x - self.width / 2, self.y - self.height / 2 x1, y1 = x0 + self.width, y0 + self.height patch = PathPatch(None, facecolor='C5', edgecolor='C6', alpha=0.5) self.updatepath(patch, x0, x1, y0, y1) self.patches = [self.patch, patch] # --------------------------------------------------------- self.connectors = dict() for key in ['u_r', 'u_l', 'u_c', 'd_r', 'd_l', 'd_c']: ud, lr = key.split('_') c = mpl.patches.Circle((self.x + self.offsets[lr], self.y - self.height / 2 + self.offsets[ud]), self.connector_radius, color='C0') self.connectors[key] = c for p in self.patches + list(self.connectors.values()): ax.add_patch(p) self.text = ax.text(self.x, self.y, text, horizontalalignment = 'center', verticalalignment = 'center', usetex=False) from matplotlib.textpath import TextToPath from matplotlib.font_manager import FontProperties fp = FontProperties(family="Helvetica", style="italic") lines = text.split("\n") for i, t in enumerate(lines): # tp = PathPatch(TextPath((self.x, self.y + i * self.height / len(lines)), t, prop=fp, size=12, usetex=False), # color="black") verts, codes = TextToPath().get_text_path(fp, t) path = mPath(verts, codes, closed=False) x0, y0 = ax.transAxes.transform((self.x, self.y)) path.vertices[:,0] = path.vertices[:,0] + x0 path.vertices[:,1] = path.vertices[:,1] + y0 + 100 * i ax.add_patch(PathPatch(ax.transAxes.inverted().transform_path(path), color='black'))
def get_marker(symbol): v, codes = TextToPath().get_text_path(fp, symbol) v = np.array(v) mean = np.mean([np.max(v,axis=0), np.min(v, axis=0)], axis=0) return Path(v-mean, codes, closed=False)
def add_level( self, energy, label, attach_last=False, energy_tag_color=None, label_color=None, line_color=None, ): """ Add a new level to the diagram energy : Energy of the new level label : tag for the new level attach_last: True [the level should be grouped with the last level] label_color line_color Returns the ID of the new level """ if self.levels: last_order = self.levels[-1].order if attach_last: level_order = last_order else: level_order = last_order + 1 else: level_order = 0 fp = FontProperties(family=configs.plot_font, size=configs.level_labels_fontsize) pathgenerator = TextToPath() pathgenerator.DPI = configs.plot_dpi verts, codes = pathgenerator.get_text_path(fp, label, ismath="TeX") text_size = Path(verts, codes).get_extents() level_width = (text_size.width / configs.plot_dpi * 1.5 + configs.level_labels_padding) if not energy_tag_color: energy_tag_color = configs.energy_tags_color if not label_color: label_color = configs.level_labels_color if not line_color: line_color = configs.level_lines_color start_position = None level_id = len(self.levels) self.levels.append( Level( level_order, energy, label, energy_tag_color, label_color, line_color, level_width, start_position, )) return level_id