Update the pixel positions of the annotation text and the arrow patch.
(self, renderer)
| 2137 | Artist.set_figure(self, fig) |
| 2138 | |
| 2139 | def update_positions(self, renderer): |
| 2140 | """ |
| 2141 | Update the pixel positions of the annotation text and the arrow patch. |
| 2142 | """ |
| 2143 | # generate transformation |
| 2144 | self.set_transform(self._get_xy_transform(renderer, self.anncoords)) |
| 2145 | |
| 2146 | arrowprops = self.arrowprops |
| 2147 | if arrowprops is None: |
| 2148 | return |
| 2149 | |
| 2150 | bbox = Text.get_window_extent(self, renderer) |
| 2151 | |
| 2152 | arrow_end = x1, y1 = self._get_position_xy(renderer) # Annotated pos. |
| 2153 | |
| 2154 | ms = arrowprops.get("mutation_scale", self.get_size()) |
| 2155 | self.arrow_patch.set_mutation_scale(ms) |
| 2156 | |
| 2157 | if "arrowstyle" not in arrowprops: |
| 2158 | # Approximately simulate the YAArrow. |
| 2159 | shrink = arrowprops.get('shrink', 0.0) |
| 2160 | width = arrowprops.get('width', 4) |
| 2161 | headwidth = arrowprops.get('headwidth', 12) |
| 2162 | headlength = arrowprops.get('headlength', 12) |
| 2163 | |
| 2164 | # NB: ms is in pts |
| 2165 | stylekw = dict(head_length=headlength / ms, |
| 2166 | head_width=headwidth / ms, |
| 2167 | tail_width=width / ms) |
| 2168 | |
| 2169 | self.arrow_patch.set_arrowstyle('simple', **stylekw) |
| 2170 | |
| 2171 | # using YAArrow style: |
| 2172 | # pick the corner of the text bbox closest to annotated point. |
| 2173 | xpos = [(bbox.x0, 0), ((bbox.x0 + bbox.x1) / 2, 0.5), (bbox.x1, 1)] |
| 2174 | ypos = [(bbox.y0, 0), ((bbox.y0 + bbox.y1) / 2, 0.5), (bbox.y1, 1)] |
| 2175 | x, relposx = min(xpos, key=lambda v: abs(v[0] - x1)) |
| 2176 | y, relposy = min(ypos, key=lambda v: abs(v[0] - y1)) |
| 2177 | self._arrow_relpos = (relposx, relposy) |
| 2178 | r = np.hypot(y - y1, x - x1) |
| 2179 | shrink_pts = shrink * r / renderer.points_to_pixels(1) |
| 2180 | self.arrow_patch.shrinkA = self.arrow_patch.shrinkB = shrink_pts |
| 2181 | |
| 2182 | # adjust the starting point of the arrow relative to the textbox. |
| 2183 | # TODO : Rotation needs to be accounted. |
| 2184 | arrow_begin = bbox.p0 + bbox.size * self._arrow_relpos |
| 2185 | # The arrow is drawn from arrow_begin to arrow_end. It will be first |
| 2186 | # clipped by patchA and patchB. Then it will be shrunk by shrinkA and |
| 2187 | # shrinkB (in points). If patchA is not set, self.bbox_patch is used. |
| 2188 | self.arrow_patch.set_positions(arrow_begin, arrow_end) |
| 2189 | |
| 2190 | if "patchA" in arrowprops: |
| 2191 | patchA = arrowprops["patchA"] |
| 2192 | elif self._bbox_patch: |
| 2193 | patchA = self._bbox_patch |
| 2194 | elif self.get_text() == "": |
| 2195 | patchA = None |
| 2196 | else: |
no test coverage detected