<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def draw_text(data, obj):
 """Paints text on the graph. """

    content = []
    properties = []
    style = []
    if isinstance(obj, mpl.text.Annotation):
        _annotation(obj, data, content)

    # 1: coordinates
    # 2: properties (shapes, rotation, etc)
    # 3: text style
    # 4: the text
    #                   -------1--------2---3--4--
    pos = obj.get_position()

    # from .util import transform_to_data_coordinates
    # pos = transform_to_data_coordinates(obj, *pos)

    text = obj.get_text()

    if text in ["", data["current axis title"]]:
        # Text nodes which are direct children of Axes are typically titles.  They are
        # already captured by the `title` property of pgfplots axes, so skip them here.
        return data, content

    size = obj.get_size()
    bbox = obj.get_bbox_patch()
    converter = mpl.colors.ColorConverter()
    # without the factor 0.5, the fonts are too big most of the time.
    # TODO fix this
    scaling = 0.5 * size / data["font size"]
    ff = data["float format"]
    if scaling != 1.0:
        properties.append(("scale=" + ff).format(scaling))

    if bbox is not None:
        _bbox(bbox, data, properties, scaling)

    ha = obj.get_ha()
    va = obj.get_va()
    anchor = _transform_positioning(ha, va)
    if anchor is not None:
        properties.append(anchor)
    data, col, _ = color.mpl_color2xcolor(data, converter.to_rgb(obj.get_color()))
    properties.append("text={}".format(col))
    properties.append("rotate={:.1f}".format(obj.get_rotation()))

    if obj.get_style() == "italic":
        style.append("\\itshape")
    else:
        assert obj.get_style() == "normal"

    # From matplotlib/font_manager.py:
    # weight_dict = {
    #     'ultralight' : 100,
    #     'light'      : 200,
    #     'normal'     : 400,
    #     'regular'    : 400,
    #     'book'       : 400,
    #     'medium'     : 500,
    #     'roman'      : 500,
    #     'semibold'   : 600,
    #     'demibold'   : 600,
    #     'demi'       : 600,
    #     'bold'       : 700,
    #     'heavy'      : 800,
    #     'extra bold' : 800,
    #     'black'      : 900}
    #
    # get_weights returns a numeric value in the range 0-1000 or one of
    # ‘light’, ‘normal’, ‘regular’, ‘book’, ‘medium’, ‘roman’, ‘semibold’,
    # ‘demibold’, ‘demi’, ‘bold’, ‘heavy’, ‘extra bold’, ‘black’
    weight = obj.get_weight()
    if weight in [
        "semibold",
        "demibold",
        "demi",
        "bold",
        "heavy",
        "extra bold",
        "black",
    ] or (isinstance(weight, int) and weight > 550):
        style.append("\\bfseries")

    # \lfseries isn't that common yet
    # elif weight == 'light' or (isinstance(weight, int) and weight < 300):
    #     style.append('\\lfseries')

    if obj.axes:
        # If the coordinates are relative to an axis, use `axis cs`.
        tikz_pos = ("(axis cs:" + ff + "," + ff + ")").format(*pos)
    else:
        # relative to the entire figure, it's a getting a littler harder. See
        # <http://tex.stackexchange.com/a/274902/13262> for a solution to the
        # problem:
        tikz_pos = (
            "({{$(current bounding box.south west)!" + ff + "!"
            "(current bounding box.south east)$}}"
            "|-"
            "{{$(current bounding box.south west)!" + ff + "!"
            "(current bounding box.north west)$}})"
        ).format(*pos)

    if "\n" in text:
        # http://tex.stackexchange.com/a/124114/13262
        properties.append("align={}".format(ha))
        # Manipulating the text here is actually against mpl2tikz's policy not
        # to do that. On the other hand, newlines should translate into
        # newlines.
        # We might want to remove this here in the future.
        text = text.replace("\n ", "\\\\")

    content.append(
        "\\node at {}[\n  {}\n]{{{}}};\n".format(
            tikz_pos, ",\n  ".join(properties), " ".join(style + [text])
        )
    )
    return data, content