'Update the graph.'

def update_graph(self):

    def text(txt, *args, **kwargs):
        return CanvasText(self.canvas, '', html_text=to_html(txt), *args, **kwargs)
    def width(txt):
        return text(txt, 0, 0, show=False).boundingRect().width()
    def fmt(val):
        return (str(int(val)) if ((val % 1) == 0) else '{:.2f}'.format(val))
    def show_pearson(rect, pearson, pen_width):
        '\n                                                Color    the    given    rectangle    according    to    its    corresponding\n                                                standardized    Pearson    residual.\n\n                                                Args:\n                                                                rect    (QRect):    the    rectangle    being    drawn\n                                                                pearson    (float):    signed    standardized    pearson    residual\n                                                                pen_width    (int):    pen    width    (bolder    pen    is    used    for    selection)\n                                                '
        r = rect.rect()
        (x, y, w, h) = (r.x(), r.y(), r.width(), r.height())
        if ((w == 0) or (h == 0)):
            return
        r = b = 255
        if (pearson > 0):
            r = g = max((255 - (20 * pearson)), 55)
        elif (pearson < 0):
            b = g = max((255 + (20 * pearson)), 55)
        else:
            r = g = b = 224
        rect.setBrush(QBrush(QColor(r, g, b)))
        pen_color = QColor((255 * (r == 255)), (255 * (g == 255)), (255 * (b == 255)))
        pen = QPen(pen_color, pen_width)
        rect.setPen(pen)
        if (pearson > 0):
            pearson = min(pearson, 10)
            dist = (20 - (1.6 * pearson))
        else:
            pearson = max(pearson, (-10))
            dist = (20 - (8 * pearson))
        pen.setWidth(1)
        def _offseted_line(ax, ay):
            r = QGraphicsLineItem((x + ax), (y + ay), (x + (ax or w)), (y + (ay or h)))
            self.canvas.addItem(r)
            r.setPen(pen)
        ax = dist
        while (ax < w):
            _offseted_line(ax, 0)
            ax += dist
        ay = dist
        while (ay < h):
            _offseted_line(0, ay)
            ay += dist
    def make_tooltip():
        'Create    the    tooltip.    The    function    uses    local    variables    from\n                                                the    enclosing    scope.'
        def _oper(attr, txt):
            if (self.data.domain[attr.name] is ddomain[attr.name]):
                return '='
            return ('    ' if (txt[0] in '<\xe2\x89\xa5') else '    in    ')
        return (((('<b>{attr_x}{xeq}{xval_name}</b>:    {obs_x}/{n}    ({p_x:.0f}    %)'.format(attr_x=to_html(attr_x.name), xeq=_oper(attr_x, xval_name), xval_name=to_html(xval_name), obs_x=fmt((chi.probs_x[x] * n)), n=int(n), p_x=(100 * chi.probs_x[x])) + '<br/>') + '<b>{attr_y}{yeq}{yval_name}</b>:    {obs_y}/{n}    ({p_y:.0f}    %)'.format(attr_y=to_html(attr_y.name), yeq=_oper(attr_y, yval_name), yval_name=to_html(yval_name), obs_y=fmt((chi.probs_y[y] * n)), n=int(n), p_y=(100 * chi.probs_y[y]))) + '<hr/>') + '<b>combination    of    values:    </b><br/>\n                                                                            &nbsp;&nbsp;&nbsp;expected    {exp}    ({p_exp:.0f}    %)<br/>\n                                                                            &nbsp;&nbsp;&nbsp;observed    {obs}    ({p_obs:.0f}    %)'.format(exp=fmt(chi.expected[(y, x)]), p_exp=((100 * chi.expected[(y, x)]) / n), obs=fmt(chi.observed[(y, x)]), p_obs=((100 * chi.observed[(y, x)]) / n)))
    for item in self.canvas.items():
        self.canvas.removeItem(item)
    if ((self.data is None) or (len(self.data) == 0) or (self.attr_x is None) or (self.attr_y is None)):
        return
    ddomain = self.discrete_data.domain
    (attr_x, attr_y) = (self.attr_x, self.attr_y)
    (disc_x, disc_y) = (ddomain[attr_x.name], ddomain[attr_y.name])
    view = self.canvasView
    chi = ChiSqStats(self.discrete_data, disc_x, disc_y)
    max_ylabel_w = max((width(val) for val in disc_y.values), default=0)
    max_ylabel_w = min(max_ylabel_w, 200)
    x_off = (width(attr_x.name) + max_ylabel_w)
    y_off = 15
    square_size = min(((view.width() - x_off) - 35), ((view.height() - y_off) - 80))
    square_size = max(square_size, 10)
    self.canvasView.setSceneRect(0, 0, view.width(), view.height())
    if ((not disc_x.values) or (not disc_y.values)):
        text_ = ('Features    {}    and    {}    have    no    values'.format(disc_x, disc_y) if ((not disc_x.values) and (not disc_y.values) and (disc_x != disc_y)) else 'Feature    {}    has    no    values'.format((disc_x if (not disc_x.values) else disc_y)))
        text(text_, ((view.width() / 2) + 70), (view.height() / 2), (Qt.AlignRight | Qt.AlignVCenter))
        return
    n = chi.n
    curr_x = x_off
    max_xlabel_h = 0
    self.areas = []
    for (x, (px, xval_name)) in enumerate(zip(chi.probs_x, disc_x.values)):
        if (px == 0):
            continue
        width = (square_size * px)
        curr_y = y_off
        for y in range((len(chi.probs_y) - 1), (-1), (-1)):
            py = chi.probs_y[y]
            yval_name = disc_y.values[y]
            if (py == 0):
                continue
            height = (square_size * py)
            selected = (len(self.areas) in self.selection)
            rect = CanvasRectangle(self.canvas, (curr_x + 2), (curr_y + 2), (width - 4), (height - 4), z=(-10), onclick=self.select_area)
            rect.value_pair = (x, y)
            self.areas.append(rect)
            show_pearson(rect, chi.residuals[(y, x)], (3 * selected))
            rect.setToolTip(make_tooltip())
            if (x == 0):
                text(yval_name, x_off, (curr_y + (height / 2)), (Qt.AlignRight | Qt.AlignVCenter))
            curr_y += height
        xl = text(xval_name, (curr_x + (width / 2)), (y_off + square_size), (Qt.AlignHCenter | Qt.AlignTop))
        max_xlabel_h = max(int(xl.boundingRect().height()), max_xlabel_h)
        curr_x += width
    bottom = ((y_off + square_size) + max_xlabel_h)
    text(attr_y.name, 0, (y_off + (square_size / 2)), (Qt.AlignLeft | Qt.AlignVCenter), bold=True, vertical=True)
    text(attr_x.name, (x_off + (square_size / 2)), bottom, (Qt.AlignHCenter | Qt.AlignTop), bold=True)
    bottom += 30
    xl = text('\xcf\x87\xc2\xb2={:.2f},    p={:.3f}'.format(chi.chisq, chi.p), 0, bottom)
    text(('N    =    ' + fmt(chi.n)), 0, (bottom - xl.boundingRect().height()))
