Skip to content

Commit b4fc581

Browse files
committed
Merge branch 'master' of https://github.com/matplotlib/matplotlib into pyplot-test-message
2 parents f42c016 + a43fd85 commit b4fc581

File tree

18 files changed

+369
-630
lines changed

18 files changed

+369
-630
lines changed

.flake8

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,12 @@ per-file-ignores =
3030

3131
matplotlib/_cm.py: E202, E203, E302
3232
matplotlib/_mathtext_data.py: E203, E261
33-
matplotlib/backend_bases.py: E225
34-
matplotlib/backends/_backend_tk.py: E203, E222, E225, E301, E401, E501
33+
matplotlib/backends/_backend_tk.py: E501
3534
matplotlib/backends/backend_agg.py: E302
3635
matplotlib/backends/backend_cairo.py: E203, E221, E402
3736
matplotlib/backends/backend_gtk3.py: E203, E221, E222, E225, E251, E501
3837
matplotlib/backends/backend_pgf.py: E731
39-
matplotlib/backends/qt_editor/formlayout.py: E301, E501
38+
matplotlib/backends/qt_editor/formlayout.py: E501
4039
matplotlib/font_manager.py: E203, E221, E251, E501
4140
matplotlib/fontconfig_pattern.py: E201, E203, E221, E222, E225
4241
matplotlib/mathtext.py: E201, E202, E203, E211, E221, E222, E225, E251, E301, E402
@@ -82,7 +81,7 @@ per-file-ignores =
8281
tutorials/introductory/images.py: E402, E501
8382
tutorials/introductory/pyplot.py: E402, E501
8483
tutorials/introductory/sample_plots.py: E501
85-
tutorials/introductory/usage.py: E402, E501
84+
tutorials/introductory/usage.py: E501
8685
tutorials/text/annotations.py: E501
8786
tutorials/text/pgf.py: E501
8887
tutorials/text/text_intro.py: E402

doc/_templates/layout.html

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,27 @@ <h3>{{ _('Navigation') }}</h3>
7676
{%- endmacro %}
7777

7878
{%- macro script() %}
79-
<script type="text/javascript">
80-
var DOCUMENTATION_OPTIONS = {
81-
URL_ROOT: '{{ url_root }}',
82-
VERSION: '{{ release|e }}',
83-
COLLAPSE_INDEX: false,
84-
FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
85-
HAS_SOURCE: {{ has_source|lower }},
86-
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
87-
};
88-
</script>
89-
{%- for scriptfile in script_files %}
90-
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
91-
{%- endfor %}
79+
{% if sphinx_version >= "1.8.0" %}
80+
<script type="text/javascript" id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
81+
{%- for scriptfile in script_files %}
82+
{{ js_tag(scriptfile) }}
83+
{%- endfor %}
84+
{% else %}
85+
<script type="text/javascript">
86+
var DOCUMENTATION_OPTIONS = {
87+
URL_ROOT:'{{ url_root }}',
88+
VERSION:'{{ release|e }}',
89+
LANGUAGE:'{{ language }}',
90+
COLLAPSE_INDEX:false,
91+
FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
92+
HAS_SOURCE: {{ has_source|lower }},
93+
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
94+
};
95+
</script>
96+
{%- for scriptfile in script_files %}
97+
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
98+
{%- endfor %}
99+
{% endif %}
92100
{%- endmacro %}
93101

94102
{%- macro css() %}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:orphan:
2+
3+
Endless Looping GIFs with PillowWriter
4+
--------------------------------------
5+
6+
We acknowledge that most people want to watch a gif more than once. Saving an animation
7+
as a gif with PillowWriter now produces an endless looping gif.

lib/matplotlib/animation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ def grab_frame(self, **savefig_kwargs):
562562
def finish(self):
563563
self._frames[0].save(
564564
self._outfile, save_all=True, append_images=self._frames[1:],
565-
duration=int(1000 / self.fps))
565+
duration=int(1000 / self.fps), loop=0)
566566

567567

568568
# Base class of ffmpeg information. Has the config keys and the common set

lib/matplotlib/axes/_axes.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import collections
12
import functools
23
import itertools
34
import logging
@@ -4184,7 +4185,11 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
41844185
valid_shape = True # will be put to the test!
41854186
n_elem = -1 # used only for (some) exceptions
41864187

4187-
if c_none or co is not None:
4188+
if (c_none or
4189+
co is not None or
4190+
isinstance(c, str) or
4191+
(isinstance(c, collections.Iterable) and
4192+
isinstance(c[0], str))):
41884193
c_array = None
41894194
else:
41904195
try: # First, does 'c' look suitable for value-mapping?

lib/matplotlib/axes/_base.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,14 +2403,16 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True):
24032403
if tight is not None:
24042404
self._tight = bool(tight)
24052405

2406-
if self.use_sticky_edges and (self._xmargin or self._ymargin):
2406+
if self.use_sticky_edges and (
2407+
(self._xmargin and scalex and self._autoscaleXon) or
2408+
(self._ymargin and scaley and self._autoscaleYon)):
24072409
stickies = [artist.sticky_edges for artist in self.get_children()]
2408-
x_stickies = sum([sticky.x for sticky in stickies], [])
2409-
y_stickies = sum([sticky.y for sticky in stickies], [])
2410+
x_stickies = np.array([x for sticky in stickies for x in sticky.x])
2411+
y_stickies = np.array([y for sticky in stickies for y in sticky.y])
24102412
if self.get_xscale().lower() == 'log':
2411-
x_stickies = [xs for xs in x_stickies if xs > 0]
2413+
x_stickies = x_stickies[x_stickies > 0]
24122414
if self.get_yscale().lower() == 'log':
2413-
y_stickies = [ys for ys in y_stickies if ys > 0]
2415+
y_stickies = y_stickies[y_stickies > 0]
24142416
else: # Small optimization.
24152417
x_stickies, y_stickies = [], []
24162418

lib/matplotlib/backend_bases.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2887,8 +2887,8 @@ def release_zoom(self, event):
28872887
# ignore singular clicks - 5 pixels is a threshold
28882888
# allows the user to "cancel" a zoom action
28892889
# by zooming by less than 5 pixels
2890-
if ((abs(x - lastx) < 5 and self._zoom_mode!="y") or
2891-
(abs(y - lasty) < 5 and self._zoom_mode!="x")):
2890+
if ((abs(x - lastx) < 5 and self._zoom_mode != "y") or
2891+
(abs(y - lasty) < 5 and self._zoom_mode != "x")):
28922892
self._xypress = None
28932893
self.release(event)
28942894
self.draw()

lib/matplotlib/backends/_backend_tk.py

Lines changed: 62 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import sys
55
import tkinter as Tk
66
from tkinter.simpledialog import SimpleDialog
7+
import tkinter.filedialog
8+
import tkinter.messagebox
79
from contextlib import contextmanager
810

911
import numpy as np
@@ -136,56 +138,56 @@ def _on_timer(self):
136138

137139

138140
class FigureCanvasTk(FigureCanvasBase):
139-
keyvald = {65507 : 'control',
140-
65505 : 'shift',
141-
65513 : 'alt',
142-
65515 : 'super',
143-
65508 : 'control',
144-
65506 : 'shift',
145-
65514 : 'alt',
146-
65361 : 'left',
147-
65362 : 'up',
148-
65363 : 'right',
149-
65364 : 'down',
150-
65307 : 'escape',
151-
65470 : 'f1',
152-
65471 : 'f2',
153-
65472 : 'f3',
154-
65473 : 'f4',
155-
65474 : 'f5',
156-
65475 : 'f6',
157-
65476 : 'f7',
158-
65477 : 'f8',
159-
65478 : 'f9',
160-
65479 : 'f10',
161-
65480 : 'f11',
162-
65481 : 'f12',
163-
65300 : 'scroll_lock',
164-
65299 : 'break',
165-
65288 : 'backspace',
166-
65293 : 'enter',
167-
65379 : 'insert',
168-
65535 : 'delete',
169-
65360 : 'home',
170-
65367 : 'end',
171-
65365 : 'pageup',
172-
65366 : 'pagedown',
173-
65438 : '0',
174-
65436 : '1',
175-
65433 : '2',
176-
65435 : '3',
177-
65430 : '4',
178-
65437 : '5',
179-
65432 : '6',
180-
65429 : '7',
181-
65431 : '8',
182-
65434 : '9',
183-
65451 : '+',
184-
65453 : '-',
185-
65450 : '*',
186-
65455 : '/',
187-
65439 : 'dec',
188-
65421 : 'enter',
141+
keyvald = {65507: 'control',
142+
65505: 'shift',
143+
65513: 'alt',
144+
65515: 'super',
145+
65508: 'control',
146+
65506: 'shift',
147+
65514: 'alt',
148+
65361: 'left',
149+
65362: 'up',
150+
65363: 'right',
151+
65364: 'down',
152+
65307: 'escape',
153+
65470: 'f1',
154+
65471: 'f2',
155+
65472: 'f3',
156+
65473: 'f4',
157+
65474: 'f5',
158+
65475: 'f6',
159+
65476: 'f7',
160+
65477: 'f8',
161+
65478: 'f9',
162+
65479: 'f10',
163+
65480: 'f11',
164+
65481: 'f12',
165+
65300: 'scroll_lock',
166+
65299: 'break',
167+
65288: 'backspace',
168+
65293: 'enter',
169+
65379: 'insert',
170+
65535: 'delete',
171+
65360: 'home',
172+
65367: 'end',
173+
65365: 'pageup',
174+
65366: 'pagedown',
175+
65438: '0',
176+
65436: '1',
177+
65433: '2',
178+
65435: '3',
179+
65430: '4',
180+
65437: '5',
181+
65432: '6',
182+
65429: '7',
183+
65431: '8',
184+
65434: '9',
185+
65451: '+',
186+
65453: '-',
187+
65450: '*',
188+
65455: '/',
189+
65439: 'dec',
190+
65421: 'enter',
189191
}
190192

191193
_keycode_lookup = {
@@ -407,12 +409,7 @@ def scroll_event(self, event):
407409
x = event.x
408410
y = self.figure.bbox.height - event.y
409411
num = getattr(event, 'num', None)
410-
if num == 4:
411-
step = +1
412-
elif num == 5:
413-
step = -1
414-
else:
415-
step = 0
412+
step = 1 if num == 4 else -1 if num == 5 else 0
416413
FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
417414

418415
def scroll_event_windows(self, event):
@@ -462,7 +459,7 @@ def _get_key(self, event):
462459
]
463460

464461
if key is not None:
465-
# note, shift is not added to the keys as this is already accounted for
462+
# shift is not added to the keys as this is already accounted for
466463
for bitmask, prefix, key_name in modifiers:
467464
if event.state & (1 << bitmask) and key_name not in key:
468465
key = '{0}+{1}'.format(prefix, key)
@@ -479,7 +476,7 @@ def key_release(self, event):
479476

480477
def new_timer(self, *args, **kwargs):
481478
"""
482-
Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
479+
Creates a new backend-specific subclass of `.backend_bases.Timer`.
483480
This is useful for getting periodic events through the backend's native
484481
event loop. Implemented only for backends with GUIs.
485482
@@ -518,9 +515,11 @@ def __init__(self, canvas, num, window):
518515
self.window.withdraw()
519516
self.set_window_title("Figure %d" % num)
520517
self.canvas = canvas
521-
# If using toolmanager it has to be present when initializing the toolbar
518+
# If using toolmanager it has to be present when initializing the
519+
# toolbar
522520
self.toolmanager = self._get_toolmanager()
523-
# packing toolbar first, because if space is getting low, last packed widget is getting shrunk first (-> the canvas)
521+
# packing toolbar first, because if space is getting low, last packed
522+
# widget is getting shrunk first (-> the canvas)
524523
self.toolbar = self._get_toolbar()
525524
self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
526525
self._num = num
@@ -582,7 +581,7 @@ def destroy(self, *args):
582581
if self.canvas._idle_callback:
583582
self.canvas._tkcanvas.after_cancel(self.canvas._idle_callback)
584583
self.window.destroy()
585-
if Gcf.get_num_fig_managers()==0:
584+
if Gcf.get_num_fig_managers() == 0:
586585
if self.window is not None:
587586
self.window.quit()
588587
self.window = None
@@ -650,7 +649,7 @@ def _Button(self, text, file, command, extension='.gif'):
650649
return b
651650

652651
def _Spacer(self):
653-
# Buttons are 30px high, so make this 26px tall with padding to center it
652+
# Buttons are 30px high. Make this 26px tall +2px padding to center it.
654653
s = Tk.Frame(
655654
master=self, height=26, relief=Tk.RIDGE, pady=2, bg="DarkGray")
656655
s.pack(side=Tk.LEFT, padx=5)
@@ -691,7 +690,6 @@ def configure_subplots(self):
691690
window.grab_set()
692691

693692
def save_figure(self, *args):
694-
import tkinter.filedialog, tkinter.messagebox
695693
filetypes = self.canvas.get_supported_filetypes().copy()
696694
default_filetype = self.canvas.get_default_filetype()
697695

@@ -817,6 +815,7 @@ def set_cursor(self, cursor):
817815

818816
class ToolbarTk(ToolContainerBase, Tk.Frame):
819817
_icon_extension = '.gif'
818+
820819
def __init__(self, toolmanager, window):
821820
ToolContainerBase.__init__(self, toolmanager)
822821
xmin, xmax = self.toolmanager.canvas.figure.bbox.intervalx
@@ -911,7 +910,6 @@ def set_message(self, s):
911910

912911
class SaveFigureTk(backend_tools.SaveFigureBase):
913912
def trigger(self, *args):
914-
import tkinter.filedialog, tkinter.messagebox
915913
filetypes = self.figure.canvas.get_supported_filetypes().copy()
916914
default_filetype = self.figure.canvas.get_default_filetype()
917915

lib/matplotlib/backends/qt_editor/formlayout.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ def is_edit_valid(edit):
207207

208208
class FormWidget(QtWidgets.QWidget):
209209
update_buttons = QtCore.Signal()
210+
210211
def __init__(self, data, comment="", parent=None):
211212
QtWidgets.QWidget.__init__(self, parent)
212213
self.data = copy.deepcopy(data)
@@ -227,7 +228,8 @@ def setup(self):
227228
for label, value in self.data:
228229
if label is None and value is None:
229230
# Separator: (None, None)
230-
self.formlayout.addRow(QtWidgets.QLabel(" "), QtWidgets.QLabel(" "))
231+
self.formlayout.addRow(QtWidgets.QLabel(" "),
232+
QtWidgets.QLabel(" "))
231233
self.widgets.append(None)
232234
continue
233235
elif label is None:
@@ -341,7 +343,8 @@ def __init__(self, datalist, comment="", parent=None):
341343

342344
self.stackwidget = QtWidgets.QStackedWidget(self)
343345
layout.addWidget(self.stackwidget)
344-
self.combobox.currentIndexChanged.connect(self.stackwidget.setCurrentIndex)
346+
self.combobox.currentIndexChanged.connect(
347+
self.stackwidget.setCurrentIndex)
345348

346349
self.widgetlist = []
347350
for data, title, comment in datalist:
@@ -425,7 +428,8 @@ def __init__(self, data, title="", comment="",
425428

426429
self.setWindowTitle(title)
427430
if not isinstance(icon, QtGui.QIcon):
428-
icon = QtWidgets.QWidget().style().standardIcon(QtWidgets.QStyle.SP_MessageBoxQuestion)
431+
icon = QtWidgets.QWidget().style().standardIcon(
432+
QtWidgets.QStyle.SP_MessageBoxQuestion)
429433
self.setWindowIcon(icon)
430434

431435
def register_float_field(self, field):

0 commit comments

Comments
 (0)