diff --git a/doc/make.py b/doc/make.py index a2f78d961479..b9409223d98b 100755 --- a/doc/make.py +++ b/doc/make.py @@ -149,13 +149,31 @@ def all(): ('mpl_toolkits/axes_grid/examples', '../../../examples/axes_grid/') ] +symlink_warnings = [] for link, target in required_symlinks: + if sys.platform == 'win32' and os.path.isfile(link): + # This is special processing that applies on platforms that don't deal + # with git symlinks -- probably only MS windows. + delete = False + with open(link, 'r') as content: + delete = target == content.read() + if delete: + symlink_warnings.append('deleted: doc/{}'.format(link)) + os.unlink(link) + else: + raise RuntimeError("doc/{} should be a directory or symlink -- it isn't") if not os.path.exists(link): if hasattr(os, 'symlink'): os.symlink(target, link) else: + symlink_warnings.append('files copied to {}'.format(link)) shutil.copytree(os.path.join(link, '..', target), link) +if sys.platform == 'win32' and len(symlink_warnings) > 0: + print('The following items related to symlinks will show up '+ + 'as spurious changes in your \'git status\':\n\t{}' + .format('\n\t'.join(symlink_warnings))) + if len(sys.argv)>1: if '--small' in sys.argv[1:]: small_docs = True diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index 0a99da1e9111..c1fee946cc26 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -56,10 +56,28 @@ legibility through brightness variations. See `here `_ for more information. -Documentation changes ---------------------- +The nbagg backend +----------------- +Phil Elson added a new backend, named "nbagg", which enables interactive +figures in a live IPython notebook session. The backend makes use of the +infrastructure developed for the webagg backend, which itself gives +standalone server backed interactive figures in the browser, however nbagg +does not require a dedicated matplotlib server as all communications are +handled through the IPython Comm machinery. + +As with other backends nbagg can be enabled inside the IPython notebook with:: + + import matplotlib + matplotlib.use('nbagg') + +Once figures are created and then subsequently shown, they will placed in an +interactive widget inside the notebook allowing panning and zooming in the +same way as any other matplotlib backend. Because figures require a connection +to the IPython notebook server for their interactivity, once the notebook is +saved, each figure will be rendered as a static image - thus allowing +non-interactive viewing of figures on services such as +`nbviewer `_. -Phil Elson rewrote of the documentation and userguide for both Legend and PathEffects (links needed). New plotting features @@ -284,6 +302,7 @@ Controls whether figures are saved with a transparent background by default. Previously `savefig` always defaulted to a non-transparent background. + ``axes.titleweight`` ```````````````````` Added rcParam to control the weight of the title @@ -296,6 +315,12 @@ an offset will be determined such that the tick labels are meaningful. If `False` then the full number will be formatted in all conditions. +``nbagg.transparent`` added +````````````````````````````` +Controls whether nbagg figures have a transparent +background. ``nbagg.transparent`` is ``True`` by default. + + XDG compliance `````````````` Matplotlib now looks for configuration files (both rcparams and style) in XDG @@ -402,6 +427,12 @@ cause the context to be reset. This allows more than one distinct context to be present in documentation. To enable this option, use ``:context: reset`` instead of ``:context:`` any time you want to reset the context. +Legend and PathEffects documentation +------------------------------------ +The :ref:`plotting-guide-legend` and :ref:`patheffects-guide` have both been +updated to better reflect the full potential of each of these powerful +features. + Widgets ------- diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 12f79352a539..9bbda6f62fa5 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -3064,6 +3064,8 @@ def boxplot(self, x, notch=False, sym=None, vert=True, whis=1.5, flierprops = dict(linestyle='none', marker='', markeredgecolor='none', markerfacecolor='none') + # turn the fliers off just to be safe + showfliers = False # now process the symbol string else: # process the symbol string diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index b325cd0a3d6d..9e25ca090b26 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -927,6 +927,15 @@ def get_numsides(self): def get_rotation(self): return self._rotation + @allow_rasterization + def draw(self, renderer): + self.set_sizes(self._sizes, self.figure.dpi) + self._transforms = [ + transforms.Affine2D(x).rotate(-self._rotation).get_matrix() + for x in self._transforms + ] + Collection.draw(self, renderer) + class StarPolygonCollection(RegularPolyCollection): """ diff --git a/lib/matplotlib/tests/baseline_images/test_collections/regularpolycollection_rotate.png b/lib/matplotlib/tests/baseline_images/test_collections/regularpolycollection_rotate.png new file mode 100644 index 000000000000..0317547b287f Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_collections/regularpolycollection_rotate.png differ diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 886dc791c9a9..e4e709ffc0f0 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -513,6 +513,22 @@ def test_polycollection_close(): ax.set_ylim3d(0, 4) +@image_comparison(baseline_images=['regularpolycollection_rotate'], + extensions=['png'], remove_text=True) +def test_regularpolycollection_rotate(): + xx, yy = np.mgrid[:10, :10] + xy_points = np.transpose([xx.flatten(), yy.flatten()]) + rotations = np.linspace(0, 2*np.pi, len(xy_points)) + + fig, ax = plt.subplots() + for xy, alpha in zip(xy_points, rotations): + col = mcollections.RegularPolyCollection( + 4, sizes=(100,), rotation=alpha, + offsets=xy, transOffset=ax.transData) + ax.add_collection(col, autolim=True) + ax.autoscale_view() + + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False)