8000 Merge branch 'v2.x' · matplotlib/matplotlib@dddb0e9 · GitHub
[go: up one dir, main page]

Skip to content

Commit dddb0e9

Browse files
committed
Merge branch 'v2.x'
2 parents 841a427 + 633add3 commit dddb0e9

File tree

9 files changed

+136
-37
lines changed

9 files changed

+136
-37
lines changed

doc/faq/howto_faq.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,7 @@ matplotlib is documented using the `sphinx
596596
extensible python framework for documentation projects which generates
597597
HTML and PDF, and is pretty easy to write; you can see the source for this
598598
document or any page on this site by clicking on the *Show Source* link
599-
at the end of the page in the sidebar (or `here
600-
<../_sources/faq/howto_faq.txt>`_ for this document).
599+
at the end of the page in the sidebar.
601600

602601
The sphinx website is a good resource for learning sphinx, but we have
603602
put together a cheat-sheet at :ref:`documenting-matplotlib` which

doc/users/whats_new/plot_surface.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
`rcount` and `ccount` for `plot_surface()`
2+
------------------------------------------
3+
4+
As of v2.0, mplot3d's :func:`~mpl_toolkits.mplot3d.axes3d.plot_surface` now
5+
accepts `rcount` and `ccount` arguments for controlling the sampling of the
6+
input data for plotting. These arguments specify the maximum number of
7+
evenly spaced samples to take from the input data. These arguments are
8+
also the new default sampling method for the function, and is
9+
considered a style change.
10+
11+
The old `rstride` and `cstride` arguments, which specified the size of the
12+
evenly spaced samples, become the default when 'classic' mode is invoked,
13+
and are still available for use. There are no plans for deprecating these
14+
arguments.
15+

examples/mplot3d/surface3d_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
Z = np.sin(R)
2929

3030
# Plot the surface.
31-
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
31+
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
3232
linewidth=0, antialiased=False)
3333

3434
# Customize the z axis.

examples/mplot3d/surface3d_demo2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@
2222
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
2323

2424
# Plot the surface
25-
ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
25+
ax.plot_surface(x, y, z, color='b')
2626

2727
plt.show()

examples/mplot3d/surface3d_demo3.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434
colors[x, y] = colortuple[(x + y) % len(colortuple)]
3535

3636
# Plot the surface with face colors taken from the array we made.
37-
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=colors,
38-
linewidth=0)
37+
surf = ax.plot_surface(X, Y, Z, facecolors=colors, linewidth=0)
3938

4039
# Customize the z axis.
4140
ax.set_zlim(-1, 1)

examples/mplot3d/surface3d_radial_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
X, Y = R*np.cos(P), R*np.sin(P)
2929

3030
# Plot the surface.
31-
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.cm.YlGnBu_r)
31+
ax.plot_surface(X, Y, Z, cmap=plt.cm.YlGnBu_r)
3232

3333
# Tweak the limits and add latex math labels.
3434
ax.set_zlim(0, 1)

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,15 +1557,28 @@ def plot_surface(self, X, Y, Z, *args, **kwargs):
15571557
15581558
The `rstride` and `cstride` kwargs set the stride used to
15591559
sample the input data to generate the graph. If 1k by 1k
1560-
arrays are passed in the default values for the strides will
1561-
result in a 100x100 grid being plotted.
1560+
arrays are passed in, the default values for the strides will
1561+
result in a 100x100 grid being plotted. Defaults to 10.
1562+
Raises a ValueError if both stride and count kwargs
1563+
(see next section) are provided.
1564+
1565+
The `rcount` and `ccount` kwargs supersedes `rstride` and
1566+
`cstride` for default sampling method for surface plotting.
1567+
These arguments will determine at most how many evenly spaced
1568+
samples will be taken from the input data to generate the graph.
1569+
This is the default sampling method unless using the 'classic'
1570+
style. Will raise ValueError if both stride and count are
1571+
specified.
1572+
Added in v2.0.0.
15621573
15631574
============= ================================================
15641575
Argument Description
15651576
============= ================================================
15661577
*X*, *Y*, *Z* Data values as 2D arrays
1567-
*rstride* Array row stride (step size), defaults to 10
1568-
*cstride* Array column stride (step size), defaults to 10
1578+
*rstride* Array row stride (step size)
1579+
*cstride* Array column stride (step size)
1580+
*rcount* Use at most this many rows, defaults to 50
1581+
*ccount* Use at most this many columns, defaults to 50
15691582
*color* Color of the surface patches
15701583
*cmap* A colormap for the surface patches.
15711584
*facecolors* Face colors for the individual patches
@@ -1587,8 +1600,30 @@ def plot_surface(self, X, Y, Z, *args, **kwargs):
15871600
X, Y, Z = np.broadcast_arrays(X, Y, Z)
15881601
rows, cols = Z.shape
15891602

1603+
has_stride = 'rstride' in kwargs or 'cstride' in kwargs
1604+
has_count = 'rcount' in kwargs or 'ccount' in kwargs
1605+
1606+
if has_stride and has_count:
1607+
raise ValueError("Cannot specify both stride and count arguments")
1608+
15901609
rstride = kwargs.pop('rstride', 10)
15911610
cstride = kwargs.pop('cstride', 10)
1611+
rcount = kwargs.pop('rcount', 50)
1612+
ccount = kwargs.pop('ccount', 50)
1613+
1614+
if rcParams['_internal.classic_mode']:
1615+
# Strides have priority over counts in classic mode.
1616+
# So, only compute strides from counts
1617+
# if counts were explicitly given
1618+
if has_count:
1619+
rstride = int(np.ceil(rows / rcount))
1620+
cstride = int(np.ceil(cols / ccount))
1621+
else:
1622+
# If the strides are provided then it has priority.
1623+
# Otherwise, compute the strides from the counts.
1624+
if not has_stride:
1625+
rstride = int(np.ceil(rows / rcount))
1626+
cstride = int(np.ceil(cols / ccount))
15921627

15931628
if 'facecolors' in kwargs:
15941629
fcolors = kwargs.pop('facecolors')
@@ -1738,7 +1773,21 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs):
17381773
The `rstride` and `cstride` kwargs set the stride used to
17391774
sample the input data to generate the graph. If either is 0
17401775
the input data in not sampled along this direction producing a
1741-
3D line plot rather than a wireframe plot.
1776+
3D line plot rather than a wireframe plot. The stride arguments
1777+
are only used by default if in the 'classic' mode. They are
1778+
now superseded by `rcount` and `ccount`. Will raise ValueError
1779+
if both stride and count are used.
1780+
1781+
` The `rcount` and `ccount` kwargs supersedes `rstride` and
1782+
`cstride` for default sampling method for wireframe plotting.
1783+
These arguments will determine at most how many evenly spaced
1784+
samples will be taken from the input data to generate the graph.
1785+
This is the default sampling method unless using the 'classic'
1786+
style. Will raise ValueError if both stride and count are
1787+
specified. If either is zero, then the input data is not sampled
1788+
along this direction, producing a 3D line plot rather than a
1789+
wireframe plot.
1790+
Added in v2.0.0.
17421791
17431792
========== ================================================
17441793
Argument Description
@@ -1747,6 +1796,8 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs):
17471796
*Z*
17481797
*rstride* Array row stride (step size), defaults to 1
17491798
*cstride* Array column stride (step size), defaults to 1
1799+
*rcount* Use at most this many rows, defaults to 50
1800+
*ccount* Use at most this many columns, defaults to 50
17501801
========== ================================================
17511802
17521803
Keyword arguments are passed on to
@@ -1755,16 +1806,38 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs):
17551806
Returns a :class:`~mpl_toolkits.mplot3d.art3d.Line3DCollection`
17561807
'''
17571808

1758-
rstride = kwargs.pop("rstride", 1)
1759-
cstride = kwargs.pop("cstride", 1)
1760-
17611809
had_data = self.has_data()
17621810
if Z.ndim != 2:
17631811
raise ValueError("Argument Z must be 2-dimensional.")
17641812
# FIXME: Support masked arrays
17651813
X, Y, Z = np.broadcast_arrays(X, Y, Z)
17661814
rows, cols = Z.shape
17671815

1816+
has_stride = 'rstride' in kwargs or 'cstride' in kwargs
1817+
has_count = 'rcount' in kwargs or 'ccount' in kwargs
1818+
1819+
if has_stride and has_count:
1820+
raise ValueError("Cannot specify both stride and count arguments")
1821+
1822+
rstride = kwargs.pop('rstride', 1)
1823+
cstride = kwargs.pop('cstride', 1)
1824+
rcount = kwargs.pop('rcount', 50)
1825+
ccount = kwargs.pop('ccount', 50)
1826+
1827+
if rcParams['_internal.classic_mode']:
1828+
# Strides have priority over counts in classic mode.
1829+
# So, only compute strides from counts
1830+
# if counts were explicitly given
1831+
if has_count:
1832+
rstride = int(np.ceil(rows / rcount)) if rcount else 0
1833+
cstride = int(np.ceil(cols / ccount)) if ccount else 0
1834+
else:
1835+
# If the strides are provided then it has priority.
1836+
# Otherwise, compute the strides from the counts.
1837+
if not has_stride:
1838+
rstride = int(np.ceil(rows / rcount)) if rcount else 0
1839+
cstride = int(np.ceil(cols / ccount)) if ccount else 0
1840+
17681841
# We want two sets of lines, one running along the "rows" of
17691842
# Z and another set of lines running along the "columns" of Z.
17701843
# This transpose will make it easy to obtain the columns.

lib/mpl_toolkits/tests/test_mplot3d.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def f(t):
107107
R = np.sqrt(X ** 2 + Y ** 2)
108108
Z = np.sin(R)
109109

110-
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
110+
surf = ax.plot_surface(X, Y, Z, rcount=40, ccount=40,
111111
linewidth=0, antialiased=False)
112112

113113
ax.set_zlim3d(-1, 1)
@@ -143,7 +143,7 @@ def test_surface3d():
143143
X, Y = np.meshgrid(X, Y)
144144
R = np.sqrt(X ** 2 + Y ** 2)
145145
Z = np.sin(R)
146-
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
146+
surf = ax.plot_surface(X, Y, Z, rcount=40, ccount=40, cmap=cm.coolwarm,
147147
lw=0, antialiased=False)
148148
ax.set_zlim(-1.01, 1.01)
149149
fig.colorbar(surf, shrink=0.5, aspect=5)
@@ -196,7 +196,7 @@ def test_wireframe3d():
196196
fig = plt.figure()
197197
ax = fig.add_subplot(111, projection='3d')
198198
X, Y, Z = axes3d.get_test_data(0.05)
199-
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
199+
ax.plot_wireframe(X, Y, Z, rcount=13, ccount=13)
200200

201201

202202
@image_comparison(baseline_images=['wireframe3dzerocstride'], remove_text=True,
@@ -205,7 +205,7 @@ def test_wireframe3dzerocstride():
205205
fig = plt.figure()
206206
ax = fig.add_subplot(111, projection='3d')
207207
X, Y, Z = axes3d.get_test_data(0.05)
208-
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=0)
208+
ax.plot_wireframe(X, Y, Z, rcount=13, ccount=0)
209209

210210

211211
@image_comparison(baseline_images=['wireframe3dzerorstride'], remove_text=True,
@@ -216,6 +216,7 @@ def test_wireframe3dzerorstride():
216216
X, Y, Z = axes3d.get_test_data(0.05)
217217
ax.plot_wireframe(X, Y, Z, rstride=0, cstride=10)
218218

219+
219220
@cleanup
220221
def test_wireframe3dzerostrideraises():
221222
fig = plt.figure()
@@ -224,6 +225,18 @@ def test_wireframe3dzerostrideraises():
224225
with assert_raises(ValueError):
225226
ax.plot_wireframe(X, Y, Z, rstride=0, cstride=0)
226227

228+
229+
@cleanup
230+
def test_mixedsamplesraises():
231+
fig = plt.figure()
232+
ax = fig.add_subplot(111, projection='3d')
233+
X, Y, Z = axes3d.get_test_data(0.05)
234+
with assert_raises(ValueError):
235+
ax.plot_wireframe(X, Y, Z, rstride=10, ccount=50)
236+
with assert_raises(ValueError):
237+
ax.plot_surface(X, Y, Z, cstride=50, rcount=10)
238+
239+
227240
@image_comparison(baseline_images=['quiver3d'], remove_text=True)
228241
def test_quiver3d():
229242
fig = plt.figure()

tools/test_triage.py

Lines changed: 18 additions & 18 deletions
< 10000 td data-grid-cell-id="diff-3d39d6372822be348ad34b040e6e3d9e1bb3c7abcffeefb26a3ebcfc981006df-137-137-1" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative diff-line-number-neutral left-side">137
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import shutil
3131
import sys
3232

33-
from PyQt4 import QtCore, QtGui
33+
from matplotlib.backends.qt_compat import QtCore, QtGui, QtWidgets
3434

3535

3636
# matplotlib stores the baseline images under two separate subtrees,
@@ -49,7 +49,7 @@
4949
exts = ['pdf', 'svg']
5050

5151

52-
class Thumbnail(QtGui.QFrame):
52+
class Thumbnail(QtWidgets.QFrame):
5353
"""
5454
Represents one of the three thumbnails at the top of the window.
5555
"""
@@ -59,14 +59,14 @@ def __init__(self, parent, index, name):
5959
self.parent = parent
6060
self.index = index
6161

62-
layout = QtGui.QVBoxLayout()
62+
layout = QtWidgets.QVBoxLayout()
6363

64-
label = QtGui.QLabel(name)
64+
label = QtWidgets.QLabel(name)
6565
label.setAlignment(QtCore.Qt.AlignHCenter |
6666
QtCore.Qt.AlignVCenter)
6767
layout.addWidget(label, 0)
6868

69-
self.image = QtGui.QLabel()
69+
self.image = QtWidgets.QLabel()
7070
self.image.setAlignment(QtCore.Qt.AlignHCenter |
7171
QtCore.Qt.AlignVCenter)
7272
self.image.setMinimumSize(800/3, 600/3)
@@ -77,7 +77,7 @@ def mousePressEvent(self, ev):
7777
self.parent.set_large_image(self.index)
7878

7979

80-
class ListWidget(QtGui.QListWidget):
80+
class ListWidget(QtWidgets.QListWidget):
8181
"""
8282
The list of files on the left-hand side
8383
"""
@@ -107,7 +107,7 @@ def eventFilter(self, receiver, event):
107107
return super(EventFilter, self).eventFilter(receiver, event)
108108

109109

110-
class Dialog(QtGui.QDialog):
110+
class Dialog(QtWidgets.QDialog):
111111
"""
112112
The main dialog window.
113113
"""
@@ -126,36 +126,36 @@ def __init__(self, entries):
126126
for entry in entries:
127127
self.filelist.addItem(entry.display)
128128

129-
images_box = QtGui.QWidget()
130-
images_layout = QtGui.QVBoxLayout()
131-
thumbnails_box = QtGui.QWidget()
132-
thumbnails_layout = QtGui.QHBoxLayout()
129+
images_box = QtWidgets.QWidget()
130+
images_layout = QtWidgets.QVBoxLayout()
131+
thumbnails_box = QtWidgets.QWidget()
132+
thumbnails_layout = QtWidgets.QHBoxLayout()
133133
self.thumbnails = []
134134
for i, name in enumerate(('test', 'expected', 'diff')):
135135
thumbnail = Thumbnail(self, i, name)
136136
thumbnails_layout.addWidget(thumbnail)
137
self.thumbnails.append(thumbnail)
138138
thumbnails_box.setLayout(thumbnails_layout)
139-
self.image_display = QtGui.QLabel()
139+
self.image_display = QtWidgets.QLabel()
140140
self.image_display.setAlignment(QtCore.Qt.AlignHCenter |
141141
QtCore.Qt.AlignVCenter)
142142
self.image_display.setMinimumSize(800, 600)
143143
images_layout.addWidget(thumbnails_box, 3)
144144
images_layout.addWidget(self.image_display, 6)
145145
images_box.setLayout(images_layout)
146146

147-
buttons_box = QtGui.QWidget()
148-
buttons_layout = QtGui.QHBoxLayout()
149-
accept_button = QtGui.QPushButton("Accept (A)")
147+
buttons_box = QtWidgets.QWidget()
148+
buttons_layout = QtWidgets.QHBoxLayout()
149+
accept_button = QtWidgets.QPushButton("Accept (A)")
150150
accept_button.clicked.connect(self.accept_test)
151151
buttons_layout.addWidget(accept_button)
152-
reject_button = QtGui.QPushButton("Reject (R)")
152+
reject_button = QtWidgets.QPushButton("Reject (R)")
153153
reject_button.clicked.connect(self.reject_test)
154154
buttons_layout.addWidget(reject_button)
155155
buttons_box.setLayout(buttons_layout)
156156
images_layout.addWidget(buttons_box)
157157

158-
main_layout = QtGui.QHBoxLayout()
158+
main_layout = QtWidgets.QHBoxLayout()
159159
main_layout.addWidget(self.filelist, 3)
160160
main_layout.addWidget(images_box, 6)
161161

@@ -358,7 +358,7 @@ def launch(result_images, source):
358358
print("No failed tests")
359359
sys.exit(0)
360360

361-
app = QtGui.QApplication(sys.argv)
361+
app = QtWidgets.QApplication(sys.argv)
362362
dialog = Dialog(entries)
363363
dialog.show()
364364
filter = EventFilter(dialog)

0 commit comments

Comments
 (0)
0