1543 | | from matplotlib.figure import Figure |
| 1579 | from matplotlib.figure import Figure, figaspect |
| 1580 | self.fontsize(fontsize) |
| 1581 | self.axes_labels(l=axes_labels) |
| 1582 | |
| 1583 | # adjust the figsize in case the user also specifies an aspect ratio |
| 1584 | if aspect_ratio is None: |
| 1585 | aspect_ratio = self.aspect_ratio() |
| 1586 | |
| 1587 | # We try to accommodate both a demand for aspect ratio and |
| 1588 | # for a figure size by adjusting the figure size to have |
| 1589 | # the right aspect ratio. |
| 1590 | if figsize is None: |
| 1591 | figsize=DEFAULT_FIGSIZE |
| 1592 | figsize=adjust_figsize_for_aspect_ratio(figsize, aspect_ratio, |
| 1593 | xmin=xmin, xmax=xmax, |
| 1594 | ymin=ymin, ymax=ymax) |
| 1595 | |
| 1596 | if figure is None: |
| 1597 | figure=Figure(figsize) |
| 1598 | |
| 1599 | #the incoming subplot instance |
| 1600 | subplot = sub |
| 1601 | if not subplot: |
| 1602 | subplot = figure.add_subplot(111) |
| 1603 | if aspect_ratio is not None: |
| 1604 | subplot.set_aspect('auto') |
| 1605 | |
| 1606 | #add all the primitives to the subplot |
| 1607 | for g in self.__objects: |
| 1608 | g._render_on_subplot(subplot) |
| 1609 | |
| 1610 | |
| 1611 | subplot.set_xlim([xmin, xmax]) |
| 1612 | subplot.set_ylim([ymin,ymax]) |
| 1613 | |
| 1614 | if axes is None: |
| 1615 | axes = self.__show_axes |
| 1616 | |
| 1617 | for spine in subplot.spines.values(): |
| 1618 | spine.set_color(self.__axes_color) |
| 1619 | spine.set_linewidth(self.__axes_width) |
| 1620 | |
| 1621 | |
| 1622 | if frame: |
| 1623 | # For now, set the formatter to the old one, since that is |
| 1624 | # sort of what we are used to. We should eventually look at |
| 1625 | # the default one to see if we like it better. |
| 1626 | from matplotlib.ticker import OldScalarFormatter |
| 1627 | subplot.xaxis.set_major_formatter(OldScalarFormatter()) |
| 1628 | subplot.yaxis.set_major_formatter(OldScalarFormatter()) |
| 1629 | |
| 1630 | subplot.set_frame_on(True) |
| 1631 | if axes: |
| 1632 | if ymin<=0 and ymax>=0: |
| 1633 | subplot.axhline(color=self.__axes_color, |
| 1634 | linewidth=self.__axes_width) |
| 1635 | if xmin<=0 and xmax>=0: |
| 1636 | subplot.axvline(color=self.__axes_color, |
| 1637 | linewidth=self.__axes_width) |
| 1638 | |
| 1639 | elif axes: |
| 1640 | ymiddle=False |
| 1641 | xmiddle=False |
| 1642 | if xmin>0: |
| 1643 | subplot.spines['right'].set_visible(False) |
| 1644 | subplot.spines['left'].set_position(('outward',10)) |
| 1645 | subplot.yaxis.set_ticks_position('left') |
| 1646 | subplot.yaxis.set_label_position('left') |
| 1647 | yaxis='left' |
| 1648 | elif xmax<0: |
| 1649 | subplot.spines['left'].set_visible(False) |
| 1650 | subplot.spines['right'].set_position(('outward',10)) |
| 1651 | subplot.yaxis.set_ticks_position('right') |
| 1652 | subplot.yaxis.set_label_position('right') |
| 1653 | yaxis='right' |
| 1654 | else: |
| 1655 | subplot.spines['left'].set_position('zero') |
| 1656 | subplot.yaxis.set_ticks_position('left') |
| 1657 | subplot.yaxis.set_label_position('left') |
| 1658 | subplot.spines['right'].set_visible(False) |
| 1659 | ymiddle=True |
| 1660 | yaxis='left' |
| 1661 | |
| 1662 | if ymin>0: |
| 1663 | subplot.spines['top'].set_visible(False) |
| 1664 | subplot.spines['bottom'].set_position(('outward',10)) |
| 1665 | subplot.xaxis.set_ticks_position('bottom') |
| 1666 | subplot.xaxis.set_label_position('bottom') |
| 1667 | xaxis='bottom' |
| 1668 | elif ymax<0: |
| 1669 | subplot.spines['bottom'].set_visible(False) |
| 1670 | subplot.spines['top'].set_position(('outward',10)) |
| 1671 | subplot.xaxis.set_ticks_position('top') |
| 1672 | subplot.xaxis.set_label_position('top') |
| 1673 | xaxis='top' |
| 1674 | else: |
| 1675 | subplot.spines['bottom'].set_position('zero') |
| 1676 | subplot.xaxis.set_ticks_position('bottom') |
| 1677 | subplot.xaxis.set_label_position('bottom') |
| 1678 | subplot.spines['top'].set_visible(False) |
| 1679 | xmiddle=True |
| 1680 | xaxis='bottom' |
| 1681 | |
| 1682 | # For now, set the formatter to the old one, since that is |
| 1683 | # sort of what we are used to. We should eventually look at |
| 1684 | # the default one to see if we like it better. |
| 1685 | from matplotlib.ticker import OldScalarFormatter |
| 1686 | subplot.xaxis.set_major_formatter(OldScalarFormatter()) |
| 1687 | subplot.yaxis.set_major_formatter(OldScalarFormatter()) |
| 1688 | |
| 1689 | |
| 1690 | # Make ticklines go on both sides of the axes |
| 1691 | # if xmiddle: |
| 1692 | # for t in subplot.xaxis.get_majorticklines(): |
| 1693 | # t.set_marker("|") |
| 1694 | # t.set_markersize(8) |
| 1695 | # for t in subplot.xaxis.get_minorticklines(): |
| 1696 | # t.set_marker("|") |
| 1697 | # t.set_markersize(4) |
| 1698 | |
| 1699 | # if ymiddle: |
| 1700 | # for t in subplot.yaxis.get_majorticklines(): |
| 1701 | # t.set_marker("|") |
| 1702 | # t.set_markersize(8) |
| 1703 | # for t in subplot.yaxis.get_minorticklines(): |
| 1704 | # t.set_marker("|") |
| 1705 | # t.set_markersize(4) |
| 1706 | |
| 1707 | # Make the zero tick labels disappear if the axes cross |
| 1708 | # inside the picture |
| 1709 | if xmiddle and ymiddle: |
| 1710 | subplot.yaxis.set_major_formatter(SelectiveFormatter(subplot.yaxis.get_major_formatter(),skip_values=[0])) |
| 1711 | subplot.xaxis.set_major_formatter(SelectiveFormatter(subplot.xaxis.get_major_formatter(),skip_values=[0])) |
| 1712 | |
| 1713 | else: |
| 1714 | for spine in subplot.spines.values(): |
| 1715 | spine.set_visible(False) |
| 1716 | from matplotlib.ticker import NullFormatter, NullLocator |
| 1717 | subplot.xaxis.set_major_formatter(NullFormatter()) |
| 1718 | subplot.yaxis.set_major_formatter(NullFormatter()) |
| 1719 | subplot.xaxis.set_major_locator(NullLocator()) |
| 1720 | subplot.yaxis.set_major_locator(NullLocator()) |
| 1721 | |
| 1722 | if frame or axes: |
| 1723 | # Make minor tickmarks |
| 1724 | from matplotlib.ticker import AutoMinorLocator |
| 1725 | subplot.xaxis.set_minor_locator(AutoMinorLocator()) |
| 1726 | subplot.yaxis.set_minor_locator(AutoMinorLocator()) |
| 1727 | |
| 1728 | ticklabels=subplot.xaxis.get_majorticklabels() + \ |
| 1729 | subplot.xaxis.get_minorticklabels() + \ |
| 1730 | subplot.yaxis.get_majorticklabels() + \ |
| 1731 | subplot.yaxis.get_minorticklabels() |
| 1732 | for ticklabel in ticklabels: |
| 1733 | ticklabel.set_fontsize(self.__fontsize) |
| 1734 | ticklabel.set_color(self.__tick_label_color) |
| 1735 | |
| 1736 | ticklines=subplot.xaxis.get_majorticklines() + \ |
| 1737 | subplot.xaxis.get_minorticklines() + \ |
| 1738 | subplot.yaxis.get_majorticklines() + \ |
| 1739 | subplot.yaxis.get_minorticklines() |
| 1740 | for tickline in ticklines: |
| 1741 | tickline.set_color(self.__axes_color) |
| 1742 | |
| 1743 | |
| 1744 | if gridlines is not None: |
| 1745 | if isinstance(gridlines, (list, tuple)): |
| 1746 | vgridlines,hgridlines=gridlines |
| 1747 | else: |
| 1748 | hgridlines=gridlines |
| 1749 | vgridlines=gridlines |
| 1750 | |
| 1751 | if gridlinesstyle is None: |
| 1752 | # Set up the default grid style |
| 1753 | gridlinesstyle=dict(color='black',linestyle=':',linewidth=0.5) |
| 1754 | |
| 1755 | vgridstyle=gridlinesstyle.copy() |
| 1756 | if vgridlinesstyle is not None: |
| 1757 | vgridstyle.update(vgridlinesstyle) |
| 1758 | |
| 1759 | hgridstyle=gridlinesstyle.copy() |
| 1760 | if hgridlinesstyle is not None: |
| 1761 | hgridstyle.update(hgridlinesstyle) |
| 1762 | |
| 1763 | if hgridlines=="minor": |
| 1764 | hgridstyle['which']="minor" |
| 1765 | if vgridlines=="minor": |
| 1766 | vgridstyle['which']="minor" |
| 1767 | |
| 1768 | if hasattr(hgridlines, '__iter__'): |
| 1769 | hlines=iter(hgridlines) |
| 1770 | hgridstyle.pop("minor",None) |
| 1771 | for hline in hlines: |
| 1772 | if isinstance(hline, (list, tuple)): |
| 1773 | hl, style=hline |
| 1774 | st=hgridstyle.copy() |
| 1775 | st.update(style) |
| 1776 | else: |
| 1777 | hl=hline |
| 1778 | st=hgridstyle |
| 1779 | subplot.axhline(hl,**st) |
| 1780 | else: |
| 1781 | if hgridlines not in (None, False): |
| 1782 | subplot.yaxis.grid(True, **hgridstyle) |
| 1783 | |
| 1784 | if hasattr(vgridlines, '__iter__'): |
| 1785 | vlines=iter(vgridlines) |
| 1786 | vgridstyle.pop("minor",None) |
| 1787 | for vline in vlines: |
| 1788 | if isinstance(vline, (list, tuple)): |
| 1789 | vl, style=vline |
| 1790 | st=vgridstyle.copy() |
| 1791 | st.update(style) |
| 1792 | else: |
| 1793 | vl=vline |
| 1794 | st=vgridstyle |
| 1795 | subplot.axvline(vl,**st) |
| 1796 | else: |
| 1797 | if vgridlines not in (None, False): |
| 1798 | subplot.xaxis.grid(True, **vgridstyle) |
| 1799 | |
| 1800 | if aspect_ratio is not None: |
| 1801 | subplot.set_aspect(aspect_ratio) |
| 1802 | |
| 1803 | |
| 1804 | if self.__axes_labels is not None: |
| 1805 | label_options={} |
| 1806 | label_options['color']=self.__axes_label_color |
| 1807 | label_options['size']=self.__fontsize |
| 1808 | subplot.set_xlabel(self.__axes_labels[0], **label_options) |
| 1809 | subplot.set_ylabel(self.__axes_labels[1], **label_options) |
| 1810 | |
| 1811 | |
| 1812 | if axes is True and frame is False: |
| 1813 | # We set the label positions according to how we are |
| 1814 | # drawing the axes. |
| 1815 | if xaxis=='bottom': |
| 1816 | yaxis_labely=1 |
| 1817 | yaxis_labeloffset=8 |
| 1818 | yaxis_vert='bottom' |
| 1819 | xaxis_labely=0 |
| 1820 | xaxis_vert='baseline' |
| 1821 | else: |
| 1822 | yaxis_labely=0 |
| 1823 | yaxis_labeloffset=-8 |
| 1824 | yaxis_vert='top' |
| 1825 | xaxis_labely=1 |
| 1826 | xaxis_vert='top' |
| 1827 | |
| 1828 | if yaxis=='left': |
| 1829 | xaxis_labelx=1 |
| 1830 | xaxis_labeloffset=8 |
| 1831 | xaxis_horiz='left' |
| 1832 | yaxis_labelx=0 |
| 1833 | else: |
| 1834 | xaxis_labelx=0 |
| 1835 | xaxis_labeloffset=-8 |
| 1836 | xaxis_horiz='right' |
| 1837 | yaxis_labelx=1 |
| 1838 | |
| 1839 | from matplotlib.transforms import offset_copy |
| 1840 | xlabel=subplot.xaxis.get_label() |
| 1841 | xlabel.set_horizontalalignment(xaxis_horiz) |
| 1842 | xlabel.set_verticalalignment(xaxis_vert) |
| 1843 | trans=subplot.spines[xaxis].get_transform() |
| 1844 | labeltrans=offset_copy(trans, figure, x=xaxis_labeloffset, y=0, units='points') |
| 1845 | subplot.xaxis.set_label_coords(x=xaxis_labelx,y=xaxis_labely,transform=labeltrans) |
| 1846 | |
| 1847 | ylabel=subplot.yaxis.get_label() |
| 1848 | ylabel.set_horizontalalignment('center') |
| 1849 | ylabel.set_verticalalignment(yaxis_vert) |
| 1850 | ylabel.set_rotation('horizontal') |
| 1851 | trans=subplot.spines[yaxis].get_transform() |
| 1852 | labeltrans=offset_copy(trans, figure, x=0, y=yaxis_labeloffset, units='points') |
| 1853 | subplot.yaxis.set_label_coords(x=yaxis_labelx,y=yaxis_labely,transform=labeltrans) |
| 1854 | |
| 1855 | #subplot.autoscale_view(tight=True) |
| 1856 | return figure |
| 1857 | |
| 1858 | def save(self, filename=None, dpi=DEFAULT_DPI, savenow=True, *args, **kwds): |
| 1859 | r""" |
| 1860 | Save the graphics to an image file of type: PNG, PS, EPS, SVG, |
| 1861 | SOBJ, depending on the file extension you give the filename. |
| 1862 | Extension types can be: ``.png``, ``.ps``, |
| 1863 | ``.eps``, ``.svg``, and |
| 1864 | ``.sobj`` (for a Sage object you can load later). |
| 1865 | |
| 1866 | |
| 1867 | EXAMPLES:: |
| 1868 | |
| 1869 | sage: c = circle((1,1),1,rgbcolor=(1,0,0)) |
| 1870 | sage: c.show(xmin=-1,xmax=3,ymin=-1,ymax=3) |
| 1871 | |
| 1872 | To correct the aspect ratio of certain graphics, you can |
| 1873 | set the ``aspect_ratio`` to 1 |
| 1874 | |
| 1875 | :: |
| 1876 | |
| 1877 | sage: c.show(aspect_ratio=1, xmin=-1, xmax=3, ymin=-1, ymax=3) |
| 1878 | |
| 1879 | You could also just make the dimensions of the picture square |
| 1880 | using ``figsize`` |
| 1881 | |
| 1882 | :: |
| 1883 | |
| 1884 | sage: c.show(figsize=[5,5], xmin=-1, xmax=3, ymin=-1, ymax=3) |
| 1885 | |
| 1886 | |
| 1887 | |
| 1888 | :: |
| 1889 | |
| 1890 | sage: point((-1,1),pointsize=30, rgbcolor=(1,0,0)) |
| 1891 | |
| 1892 | By default, the figure grows to include all of the graphics |
| 1893 | and text, so the final image may not be exactly the figure |
| 1894 | size you specified. |
| 1895 | """ |
1558 | | if figure is None: |
1559 | | figure = Figure(figsize) |
1560 | | |
1561 | | #The line below takes away the excessive whitespace around |
1562 | | #images. ('figsize' and 'dpi' still work as expected): |
1563 | | figure.subplots_adjust(left=0.04, bottom=0.04, right=0.96, top=0.96) |
1564 | | |
1565 | | #the incoming subplot instance |
1566 | | subplot = sub |
1567 | | if not subplot: |
1568 | | subplot = figure.add_subplot(111) |
1569 | | |
1570 | | #take away the matplotlib axes: |
1571 | | subplot.xaxis.set_visible(False) |
1572 | | subplot.yaxis.set_visible(False) |
1573 | | subplot.set_frame_on(False) |
1574 | | |
1575 | | #add all the primitives to the subplot |
1576 | | #check if there are any ContourPlot instances |
1577 | | #in self._objects, and if so change the axes |
1578 | | #to be frame axes instead of centered axes |
1579 | | contour = False |
1580 | | plotfield = False |
1581 | | matrixplot = False |
1582 | | from contour_plot import ContourPlot |
1583 | | from matrix_plot import MatrixPlot |
1584 | | from plot_field import PlotField |
1585 | | for g in self.__objects: |
1586 | | if isinstance(g, ContourPlot): |
1587 | | contour = True |
1588 | | if isinstance(g, PlotField): |
1589 | | plotfield = True |
1590 | | if isinstance(g, MatrixPlot): |
1591 | | matrixplot = True |
1592 | | g._render_on_subplot(subplot) |
1593 | | |
1594 | | #adjust the xy limits and draw the axes: |
1595 | | if axes is None: |
1596 | | axes = self.__show_axes |
1597 | | |
1598 | | #construct an Axes instance, see 'axes.py' for relevant code |
1599 | | sage_axes = Axes(color=self.__axes_color, fontsize=self.__fontsize, |
1600 | | axes_labels=self.__axes_labels, |
1601 | | axes_label_color=self.__axes_label_color, |
1602 | | tick_label_color=self.__tick_label_color, linewidth=self.__axes_width) |
1603 | | |
1604 | | # construct a GridLines instance, see 'axes.py' for relevant code |
1605 | | sage_gridlines = GridLines(gridlines=gridlines, gridlinesstyle=gridlinesstyle, |
1606 | | vgridlinesstyle=vgridlinesstyle, hgridlinesstyle=hgridlinesstyle) |
1607 | | |
1608 | | #adjust the xy limits and draw the axes: |
1609 | | if not (contour or plotfield or matrixplot): #the plot is a 'regular' plot |
1610 | | xmin -= 0.1*(xmax-xmin) |
1611 | | xmax += 0.1*(xmax-xmin) |
1612 | | ymin -= 0.1*(ymax-ymin) |
1613 | | ymax += 0.1*(ymax-ymin) |
1614 | | if frame: #add the frame axes |
1615 | | axmin, axmax = xmin - 0.04*abs(xmax - xmin), xmax + 0.04*abs(xmax - xmin) |
1616 | | aymin, aymax = ymin - 0.04*abs(ymax - ymin), ymax + 0.04*abs(ymax - ymin) |
1617 | | subplot.set_xlim([axmin, axmax]) |
1618 | | subplot.set_ylim([aymin, aymax]) |
1619 | | # draw the grid |
1620 | | sage_gridlines.add_gridlines(subplot, xmin, xmax, ymin, ymax, True) |
1621 | | #add a frame to the plot and possibly 'axes_with_no_ticks' |
1622 | | sage_axes.add_xy_frame_axes(subplot, xmin, xmax, ymin, ymax, |
1623 | | axes_with_no_ticks=axes) |
1624 | | |
1625 | | elif not frame and axes: #regular plot with regular axes |
1626 | | # draw the grid |
1627 | | sage_gridlines.add_gridlines(subplot, xmin, xmax, ymin, ymax, False) |
1628 | | # draw the axes |
1629 | | xmin, xmax, ymin, ymax = sage_axes.add_xy_axes(subplot, xmin, xmax, ymin, ymax) |
1630 | | subplot.set_xlim(xmin, xmax) |
1631 | | subplot.set_ylim(ymin, ymax) |
1632 | | |
1633 | | else: #regular plot with no axes |
1634 | | subplot.set_xlim(xmin, xmax) |
1635 | | subplot.set_ylim(ymin, ymax) |
1636 | | # draw the grid |
1637 | | sage_gridlines.add_gridlines(subplot, xmin, xmax, ymin, ymax, False) |
1638 | | |
1639 | | elif (contour or plotfield): #contour or field plot in self.__objects, so adjust axes accordingly |
1640 | | subplot.set_xlim([xmin - 0.05*abs(xmax - xmin), xmax + 0.05*abs(xmax - xmin)]) |
1641 | | subplot.set_ylim([ymin - 0.05*abs(ymax - ymin), ymax + 0.05*abs(ymax - ymin)]) |
1642 | | # draw the grid |
1643 | | sage_gridlines.add_gridlines(subplot, xmin, xmax, ymin, ymax, True) |
1644 | | # draw the axes |
1645 | | if axes: #axes=True unless user specifies axes=False |
1646 | | sage_axes.add_xy_frame_axes(subplot, xmin, xmax, ymin, ymax) |
1647 | | |
1648 | | else: #we have a 'matrix_plot' in self.__objects, so adjust axes accordingly |
1649 | | subplot.set_xlim([xmin - 0.05*abs(xmax - xmin), xmax + 0.05*abs(xmax - xmin)]) |
1650 | | subplot.set_ylim([ymin - 0.05*abs(ymax - ymin), ymax + 0.05*abs(ymax - ymin)]) |
1651 | | # draw the grid |
1652 | | if gridlines in ["major", "automatic", True]: |
1653 | | gridlines = [sage.misc.misc.srange(-0.5,xmax+1,1), |
1654 | | sage.misc.misc.srange(-0.5,ymax+1,1)] |
1655 | | sage_gridlines = GridLines(gridlines=gridlines, |
1656 | | gridlinesstyle=gridlinesstyle, |
1657 | | vgridlinesstyle=vgridlinesstyle, |
1658 | | hgridlinesstyle=hgridlinesstyle) |
1659 | | sage_gridlines.add_gridlines(subplot, xmin, xmax, ymin, ymax, False) |
1660 | | # draw the axes |
1661 | | if axes: #axes=True unless user specifies axes=False |
1662 | | sage_axes.add_xy_matrix_frame_axes(subplot, xmin, xmax, ymin, ymax) |
1663 | | |
1664 | | # You can output in PNG, PS, EPS, PDF, or SVG format, depending on the file extension. |
1665 | | # matplotlib looks at the file extension to see what the renderer should be. |
1666 | | # The default is FigureCanvasAgg for PNG's because this is by far the most |
1667 | | # common type of files rendered, like in the Notebook for example. |
1668 | | # if the file extension is not '.png', then matplotlib will handle it. |
1669 | | if savenow: |
1670 | | from matplotlib.backends.backend_agg import FigureCanvasAgg |
1671 | | canvas = FigureCanvasAgg(figure) |
1683 | | canvas.print_figure(filename, dpi=dpi) |
| 1930 | #if kwds['bbox'] is not None: |
| 1931 | # options['bbox_inches']=kwds['bbox'] |
| 1932 | #else: |
| 1933 | # canvas.mpl_connect('draw_event', on_draw) |
| 1934 | #options['bbox_inches']=figure.get_size_inches() |
| 1935 | figure.savefig(filename,dpi=dpi,bbox_inches='tight',**options) |
| 1936 | #canvas.print_figure(filename, dpi=dpi,**options) |
| 1937 | |
| 1938 | |
| 1939 | |
| 1940 | from matplotlib.ticker import Formatter |
| 1941 | |
| 1942 | class SelectiveFormatter(Formatter): |
| 1943 | """TODO: write documentation for each function""" |
| 1944 | def __init__(self, formatter,skip_values): |
| 1945 | self.formatter=formatter |
| 1946 | self.skip_values=skip_values |
| 1947 | def set_locs(self, locs): |
| 1948 | self.formatter.set_locs([l for l in locs if l not in self.skip_values]) |
| 1949 | def __call__(self, x, *args, **kwds): |
| 1950 | """Return the format for tick val *x* at position *pos*""" |
| 1951 | if x in self.skip_values: |
| 1952 | return '' |
| 1953 | else: |
| 1954 | return self.formatter(x, *args, **kwds) |
| 1955 | |
| 1956 | def on_draw(event): |
| 1957 | """ |
| 1958 | TODO: write documentation |
| 1959 | """ |
| 1960 | import matplotlib.transforms as mtransforms |
| 1961 | figure=event.canvas.figure |
| 1962 | bboxes = [] |
| 1963 | for ax in figure.axes: |
| 1964 | bbox = ax.xaxis.get_label().get_window_extent() |
| 1965 | # the figure transform goes from relative coords->pixels and we |
| 1966 | # want the inverse of that |
| 1967 | bboxi = bbox.inverse_transformed(figure.transFigure) |
| 1968 | bboxes.append(bboxi) |
| 1969 | |
| 1970 | bbox = ax.yaxis.get_label().get_window_extent() |
| 1971 | bboxi = bbox.inverse_transformed(figure.transFigure) |
| 1972 | bboxes.append(bboxi) |
| 1973 | for label in (ax.get_xticklabels()+ax.get_yticklabels() \ |
| 1974 | + ax.get_xticklabels(minor=True) \ |
| 1975 | +ax.get_yticklabels(minor=True)): |
| 1976 | bbox = label.get_window_extent() |
| 1977 | bboxi = bbox.inverse_transformed(figure.transFigure) |
| 1978 | bboxes.append(bboxi) |
| 1979 | |
| 1980 | # this is the bbox that bounds all the bboxes, again in relative |
| 1981 | # figure coords |
| 1982 | bbox = mtransforms.Bbox.union(bboxes) |
| 1983 | adjusted=adjust_figure_to_contain_bbox(figure,bbox) |
| 1984 | |
| 1985 | if adjusted: |
| 1986 | figure.canvas.draw() |
| 1987 | return False |
| 1988 | |
| 1989 | def adjust_figure_to_contain_bbox(fig, bbox): |
| 1990 | """ |
| 1991 | TODO: write documentation |
| 1992 | """ |
| 1993 | adjusted=False |
| 1994 | if bbox.xmin<0: |
| 1995 | fig.subplots_adjust(left=fig.subplotpars.left-bbox.xmin) |
| 1996 | adjusted=True |
| 1997 | if bbox.ymin<0: |
| 1998 | fig.subplots_adjust(bottom=fig.subplotpars.bottom-bbox.ymin) |
| 1999 | adjusted=True |
| 2000 | if bbox.xmax>1: |
| 2001 | fig.subplots_adjust(right=fig.subplotpars.right-(bbox.xmax-1)) |
| 2002 | adjusted=True |
| 2003 | if bbox.ymax>1: |
| 2004 | fig.subplots_adjust(top=fig.subplotpars.top-(bbox.ymax-1)) |
| 2005 | adjusted=True |
| 2006 | return adjusted |