|
8 | 8 |
|
9 | 9 | import matplotlib as mpl
|
10 | 10 | from matplotlib.backend_bases import MouseEvent
|
| 11 | +from matplotlib.backends.backend_agg import RendererAgg |
| 12 | +from matplotlib.figure import Figure |
11 | 13 | from matplotlib.font_manager import FontProperties
|
12 | 14 | import matplotlib.patches as mpatches
|
13 | 15 | import matplotlib.pyplot as plt
|
@@ -962,3 +964,150 @@ def test_text_antialiased_on_default_vs_manual(fig_test, fig_ref):
|
962 | 964 |
|
963 | 965 | mpl.rcParams['text.antialiased'] = True
|
964 | 966 | fig_ref.text(0.5, 0.5, '6 inches x 2 inches')
|
| 967 | + |
| 968 | + |
| 969 | +def test_text_annotation_get_window_extent(): |
| 970 | + figure = Figure(dpi=100) |
| 971 | + renderer = RendererAgg(200, 200, 100) |
| 972 | + |
| 973 | + # Only text annotation |
| 974 | + annotation = Annotation('test', xy=(0, 0)) |
| 975 | + annotation.set_figure(figure) |
| 976 | + |
| 977 | + text = Text(text='test', x=0, y=0) |
| 978 | + text.set_figure(figure) |
| 979 | + |
| 980 | + bbox = annotation.get_window_extent(renderer=renderer) |
| 981 | + |
| 982 | + text_bbox = text.get_window_extent(renderer=renderer) |
| 983 | + assert bbox.width == text_bbox.width |
| 984 | + assert bbox.height == text_bbox.height |
| 985 | + |
| 986 | + _, _, d = renderer.get_text_width_height_descent( |
| 987 | + 'text', annotation._fontproperties, ismath=False) |
| 988 | + _, _, lp_d = renderer.get_text_width_height_descent( |
| 989 | + 'lp', annotation._fontproperties, ismath=False) |
| 990 | + below_line = max(d, lp_d) |
| 991 | + |
| 992 | + # These numbers are specific to the current implementation of Text |
| 993 | + points = bbox.get_points() |
| 994 | + assert points[0, 0] == 0.0 |
| 995 | + assert points[1, 0] == text_bbox.width |
| 996 | + assert points[0, 1] == -below_line |
| 997 | + assert points[1, 1] == text_bbox.height - below_line |
| 998 | + |
| 999 | + |
| 1000 | +def test_text_with_arrow_annotation_get_window_extent(): |
| 1001 | + headwidth = 21 |
| 1002 | + fig, ax = plt.subplots(dpi=100) |
| 1003 | + txt = ax.text(s='test', x=0, y=0) |
| 1004 | + ann = ax.annotate( |
| 1005 | + 'test', |
| 1006 | + xy=(0.0, 50.0), |
| 1007 | + xytext=(50.0, 50.0), xycoords='figure pixels', |
| 1008 | + arrowprops={ |
| 1009 | + 'facecolor': 'black', 'width': 2, |
| 1010 | + 'headwidth': headwidth, 'shrink': 0.0}) |
| 1011 | + |
| 1012 | + plt.draw() |
| 1013 | + renderer = fig.canvas.renderer |
| 1014 | + # bounding box of text |
| 1015 | + text_bbox = txt.get_window_extent(renderer=renderer) |
| 1016 | + # bounding box of annotation (text + arrow) |
| 1017 | + bbox = ann.get_window_extent(renderer=renderer) |
| 1018 | + # bounding box of arrow |
| 1019 | + arrow_bbox = ann.arrow_patch.get_window_extent(renderer) |
| 1020 | + # bounding box of annotation text |
| 1021 | + ann_txt_bbox = Text.get_window_extent(ann) |
| 1022 | + |
| 1023 | + # make sure annotation width is 50 px wider than |
| 1024 | + # just the text |
| 1025 | + assert bbox.width == text_bbox.width + 50.0 |
| 1026 | + # make sure the annotation text bounding box is same size |
| 1027 | + # as the bounding box of the same string as a Text object |
| 1028 | + assert ann_txt_bbox.height == text_bbox.height |
| 1029 | + assert ann_txt_bbox.width == text_bbox.width |
| 1030 | + # compute the expected bounding box of arrow + text |
| 1031 | + expected_bbox = mtransforms.Bbox.union([ann_txt_bbox, arrow_bbox]) |
| 1032 | + assert_almost_equal(bbox.height, expected_bbox.height) |
| 1033 | + |
| 1034 | + |
| 1035 | +def test_arrow_annotation_get_window_extent(): |
| 1036 | + dpi = 100 |
| 1037 | + dots_per_point = dpi / 72 |
| 1038 | + figure = Figure(dpi=dpi) |
| 1039 | + figure.set_figwidth(2.0) |
| 1040 | + figure.set_figheight(2.0) |
| 1041 | + renderer = RendererAgg(200, 200, 100) |
| 1042 | + |
| 1043 | + # Text annotation with arrow; arrow dimensions are in points |
| 1044 | + annotation = Annotation( |
| 1045 | + '', xy=(0.0, 50.0), xytext=(50.0, 50.0), xycoords='figure pixels', |
| 1046 | + arrowprops={ |
| 1047 | + 'facecolor': 'black', 'width': 8, 'headwidth': 10, 'shrink': 0.0}) |
| 1048 | + annotation.set_figure(figure) |
| 1049 | + annotation.draw(renderer) |
| 1050 | + |
| 1051 | + bbox = annotation.get_window_extent() |
| 1052 | + points = bbox.get_points() |
| 1053 | + |
| 1054 | + assert bbox.width == 50.0 |
| 1055 | + assert_almost_equal(bbox.height, 10.0 * dots_per_point) |
| 1056 | + assert points[0, 0] == 0.0 |
| 1057 | + assert points[0, 1] == 50.0 - 5 * dots_per_point |
| 1058 | + |
| 1059 | + |
| 1060 | +def test_empty_annotation_get_window_extent(): |
| 1061 | + figure = Figure(dpi=100) |
| 1062 | + figure.set_figwidth(2.0) |
| 1063 | + figure.set_figheight(2.0) |
| 1064 | + renderer = RendererAgg(200, 200, 100) |
| 1065 | + |
| 1066 | + # Text annotation with arrow |
| 1067 | + annotation = Annotation( |
| 1068 | + '', xy=(0.0, 50.0), xytext=(0.0, 50.0), xycoords='figure pixels') |
| 1069 | + annotation.set_figure(figure) |
| 1070 | + annotation.draw(renderer) |
| 1071 | + |
| 1072 | + bbox = annotation.get_window_extent() |
| 1073 | + points = bbox.get_points() |
| 1074 | + |
| 1075 | + assert points[0, 0] == 0.0 |
| 1076 | + assert points[1, 0] == 0.0 |
| 1077 | + assert points[1, 1] == 50.0 |
| 1078 | + assert points[0, 1] == 50.0 |
| 1079 | + |
| 1080 | + |
| 1081 | +@image_comparison(baseline_images=['basictext_wrap'], |
| 1082 | + extensions=['png']) |
| 1083 | +def test_basic_wrap(): |
| 1084 | + fig = plt.figure() |
| 1085 | + plt.axis([0, 10, 0, 10]) |
| 1086 | + t = "This is a really long string that I'd rather have wrapped so that" \ |
| 1087 | + " it doesn't go outside of the figure, but if it's long enough it" \ |
| 1088 | + " will go off the top or bottom!" |
| 1089 | + plt.text(4, 1, t, ha='left', rotation=15, wrap=True) |
| 1090 | + plt.text(6, 5, t, ha='left', rotation=15, wrap=True) |
| 1091 | + plt.text(5, 5, t, ha='right', rotation=-15, wrap=True) |
| 1092 | + plt.text(5, 10, t, fontsize=18, style='oblique', ha='center', |
| 1093 | + va='top', wrap=True) |
| 1094 | + plt.text(3, 4, t, family='serif', style='italic', ha='right', wrap=True) |
| 1095 | + plt.text(-1, 0, t, ha='left', rotation=-15, wrap=True) |
| 1096 | + |
| 1097 | + |
| 1098 | +@image_comparison(baseline_images=['fonttext_wrap'], |
| 1099 | + extensions=['png']) |
| 1100 | +def test_font_wrap(): |
| 1101 | + fig = plt.figure() |
| 1102 | + plt.axis([0, 10, 0, 10]) |
| 1103 | + t = "This is a really long string that I'd rather have wrapped so that" \ |
| 1104 | + " it doesn't go outside of the figure, but if it's long enough it" \ |
| 1105 | + " will go off the top or bottom!" |
| 1106 | + plt.text(4, -1, t, fontsize=18, family='serif', ha='left', rotation=15, |
| 1107 | + wrap=True) |
| 1108 | + plt.text(6, 5, t, family='sans serif', ha='left', rotation=15, wrap=True) |
| 1109 | + plt.text(5, 5, t, weight='light', ha='right', rotation=-15, wrap=True) |
| 1110 | + plt.text(5, 10, t, weight='heavy', ha='center', va='top', wrap=True) |
| 1111 | + plt.text(3, 4, t, family='monospace', ha='right', wrap=True) |
| 1112 | + plt.text(-1, 0, t, fontsize=14, style='italic', ha='left', rotation=-15, |
| 1113 | + wrap=True) |
0 commit comments