X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
2013-04-15 Added 'axes.xmargin' and 'axes.ymargin' to rpParams to set default
margins on auto-scaleing. - TAC

2013-04-16 Added patheffect support for Line2D objects. -JJL

2013-03-19 Added support for passing `linestyle` kwarg to `step` so all `plot`
kwargs are passed to the underlying `plot` call. -TAC

Expand Down
7 changes: 6 additions & 1 deletion doc/api/api_changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ For new features that were added to matplotlib, please see
Changes in 1.3.x
================

* Fixed a bug in setting the position for the right/top spine with data
* The `font.*` rcParams now affect only text objects created after the
rcParam has been set, and will not retroactively affect already
existing text objects. This brings their behavior in line with most
other rcParams.

* Fixed a bug in setting the position for the right/top spine with data
position type. Previously, it would draw the right or top spine at
+1 data offset.

Expand Down
28 changes: 26 additions & 2 deletions doc/users/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@ revision, see the :ref:`github-stats`.

new in matplotlib-1.3
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path effects on lines deserves to go in here too.

=====================
`xkcd`-style sketch plotting
----------------------------

To give your plots a sense of authority that they may be missing,
Michael Droettboom (inspired by the work of many others in
:ghpull:`1329`) has added an `xkcd-style <http://xkcd.com/>`_ sketch
plotting mode. To use it, simply call `pyplot.xkcd` before creating
your plot.

.. plot:: mpl_examples/showcase/xkcd.py

Path effects on lines
---------------------
Thanks to Jae-Joon Lee, path effects now also work on plot lines.

.. plot:: mpl_examples/pylab_examples/patheffect_demo.py

Changes to font rcParams
------------------------
The `font.*` rcParams now affect only text objects created after the
rcParam has been set, and will not retroactively affect already
existing text objects. This brings their behavior in line with most
other rcParams.

``axes.xmargin`` and ``axes.ymargin`` added to rcParams
-------------------------------------------------------
``rcParam`` values (``axes.xmargin`` and ``axes.ymargin``) were added
Expand Down Expand Up @@ -142,8 +166,8 @@ the bottom of the text bounding box.

``savefig.jpeg_quality`` added to rcParams
------------------------------------------------------------------------------
``rcParam`` value ``savefig.jpeg_quality`` was added so that the user can
configure the default quality used when a figure is written as a JPEG. The
``rcParam`` value ``savefig.jpeg_quality`` was added so that the user can
configure the default quality used when a figure is written as a JPEG. The
default quality is 95; previously, the default quality was 75. This change
minimizes the artifacting inherent in JPEG images, particularly with images
that have sharp changes in color as plots often do.
Expand Down
24 changes: 16 additions & 8 deletions examples/pylab_examples/patheffect_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,28 @@

txt.set_path_effects([PathEffects.withStroke(linewidth=3,
foreground="w")])
txt.arrow_patch.set_path_effects([PathEffects.Stroke(linewidth=5,
foreground="w"),
PathEffects.Normal()])
txt.arrow_patch.set_path_effects([
PathEffects.Stroke(linewidth=5, foreground="w"),
PathEffects.Normal()])

ax1.grid(True, linestyle="-")

pe = [PathEffects.withStroke(linewidth=3,
foreground="w")]
for l in ax1.get_xgridlines() + ax1.get_ygridlines():
l.set_path_effects(pe)

ax2 = plt.subplot(132)
arr = np.arange(25).reshape((5,5))
ax2.imshow(arr)
cntr = ax2.contour(arr, colors="k")
clbls = ax2.clabel(cntr, fmt="%2.0f", use_clabeltext=True)
plt.setp(clbls,
path_effects=[PathEffects.withStroke(linewidth=3,
foreground="w")])

plt.setp(cntr.collections, path_effects=[
PathEffects.withStroke(linewidth=3, foreground="w")])

clbls = ax2.clabel(cntr, fmt="%2.0f", use_clabeltext=True)
plt.setp(clbls, path_effects=[
PathEffects.withStroke(linewidth=3, foreground="w")])

# shadow as a path effect
ax3 = plt.subplot(133)
Expand All @@ -34,4 +43,3 @@
leg.legendPatch.set_path_effects([PathEffects.withSimplePatchShadow()])

plt.show()

2 changes: 1 addition & 1 deletion examples/pylab_examples/simple_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

t = arange(0.0, 2.0, 0.01)
s = sin(2*pi*t)
plot(t, s, linewidth=1.0)
plot(t, s)

xlabel('time (s)')
ylabel('voltage (mV)')
Expand Down
4 changes: 3 additions & 1 deletion examples/pylab_examples/to_numeric.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@
X.shape = h, w, 3

im = Image.fromstring( "RGB", (w,h), s)
im.show()

# Uncomment this line to display the image using ImageMagick's
# `display` tool.
# im.show()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes -- though I should probably remove the line altogether -- this causes ImageMagick's "display" utility to be called during the documentation build.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! That annoys me everytime and I've never got to the bottom of it! 😄

54 changes: 54 additions & 0 deletions examples/showcase/xkcd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import matplotlib.pyplot as plt
import numpy as np

with plt.xkcd():
# Based on "Stove Ownership" from XKCD by Randall Monroe
# http://xkcd.com/418/

fig = plt.figure()
ax = fig.add_axes((0.1, 0.2, 0.8, 0.7))
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.xticks([])
plt.yticks([])
ax.set_ylim([-30, 10])

data = np.ones(100)
data[70:] -= np.arange(30)

plt.annotate(
'THE DAY I REALIZED\nI COULD COOK BACON\nWHENEVER I WANTED',
xy=(70, 1), arrowprops=dict(arrowstyle='->'), xytext=(15, -10))

plt.plot(data)

plt.xlabel('time')
plt.ylabel('my overall health')
fig.text(
0.5, 0.05,
'"Stove Ownership" from xkcd by Randall Monroe',
ha='center')

# Based on "The Data So Far" from XKCD by Randall Monroe
# http://xkcd.com/373/

fig = plt.figure()
ax = fig.add_axes((0.1, 0.2, 0.8, 0.7))
ax.bar([-0.125, 1.0-0.125], [0, 100], 0.25)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.set_xticks([0, 1])
ax.set_xlim([-0.5, 1.5])
ax.set_ylim([0, 110])
ax.set_xticklabels(['CONFIRMED BY\nEXPERIMENT', 'REFUTED BY\nEXPERIMENT'])
plt.yticks([])

plt.title("CLAIMS OF SUPERNATURAL POWERS")

fig.text(
0.5, 0.05,
'"The Data So Far" from xkcd by Randall Monroe',
ha='center')

plt.show()
6 changes: 5 additions & 1 deletion lib/matplotlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,12 +1050,15 @@ class rc_context(object):
def __init__(self, rc=None, fname=None):
self.rcdict = rc
self.fname = fname
def __enter__(self):
self._rcparams = rcParams.copy()
if self.fname:
rc_file(self.fname)
if self.rcdict:
rcParams.update(self.rcdict)

def __enter__(self):
return self

def __exit__(self, type, value, tb):
rcParams.update(self._rcparams)

Expand Down Expand Up @@ -1188,6 +1191,7 @@ def tk_window_focus():
'matplotlib.tests.test_mathtext',
'matplotlib.tests.test_mlab',
'matplotlib.tests.test_patches',
'matplotlib.tests.test_patheffects',
'matplotlib.tests.test_pickle',
'matplotlib.tests.test_rcparams',
'matplotlib.tests.test_scale',
Expand Down
63 changes: 62 additions & 1 deletion lib/matplotlib/artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ def __init__(self):
self._url = None
self._gid = None
self._snap = None
self._sketch = rcParams['path.sketch']
self._path_effects = rcParams['path.effects']

def __getstate__(self):
d = self.__dict__.copy()
Expand Down Expand Up @@ -456,6 +458,63 @@ def set_snap(self, snap):
"""
self._snap = snap

def get_sketch_params(self):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be keen to use numpydoc form here (https://github.com/matplotlib/matplotlib/wiki/Mep10)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sure -- I didn't notice that. This PR predates MEP10, so I forgot to update it.

"""
Returns the sketch parameters for the artist.

Returns
-------
sketch_params : tuple or `None`

A 3-tuple with the following elements:

* `scale`: The amplitude of the wiggle perpendicular to the
source line.

* `length`: The length of the wiggle along the line.

* `randomness`: The scale factor by which the length is
shrunken or expanded.

May return `None` if no sketch parameters were set.
"""
return self._sketch

def set_sketch_params(self, scale=None, length=None, randomness=None):
"""
Sets the the sketch parameters.

Parameters
----------

scale : float, optional
The amplitude of the wiggle perpendicular to the source
line, in pixels. If scale is `None`, or not provided, no
sketch filter will be provided.

length : float, optional
The length of the wiggle along the line, in pixels
(default 128.0)

randomness : float, optional
The scale factor by which the length is shrunken or
expanded (default 16.0)
"""
if scale is None:
self._sketch = None
else:
self._sketch = (scale, length or 128.0, randomness or 16.0)

def set_path_effects(self, path_effects):
"""
set path_effects, which should be a list of instances of
matplotlib.patheffect._Base class or its derivatives.
"""
self._path_effects = path_effects

def get_path_effects(self):
return self._path_effects

def get_figure(self):
"""
Return the :class:`~matplotlib.figure.Figure` instance the
Expand Down Expand Up @@ -672,7 +731,7 @@ def update(self, props):
store = self.eventson
self.eventson = False
changed = False

for k, v in props.iteritems():
func = getattr(self, 'set_' + k, None)
if func is None or not callable(func):
Expand Down Expand Up @@ -728,6 +787,8 @@ def update_from(self, other):
self._clippath = other._clippath
self._lod = other._lod
self._label = other._label
self._sketch = other._sketch
self._path_effects = other._path_effects
self.pchanged()

def properties(self):
Expand Down
53 changes: 51 additions & 2 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ def __init__(self):
self._url = None
self._gid = None
self._snap = None
self._sketch = None

def copy_properties(self, gc):
'Copy properties from gc to self'
Expand All @@ -720,6 +721,7 @@ def copy_properties(self, gc):
self._url = gc._url
self._gid = gc._gid
self._snap = gc._snap
self._sketch = gc._sketch

def restore(self):
"""
Expand Down Expand Up @@ -1003,6 +1005,53 @@ def get_hatch_path(self, density=6.0):
return None
return Path.hatch(self._hatch, density)

def get_sketch_params(self):
"""
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not an action: We should think about removing the duplicated docstings (duplicated in Artist) from here.

Returns the sketch parameters for the artist.

Returns
-------
sketch_params : tuple or `None`

A 3-tuple with the following elements:

* `scale`: The amplitude of the wiggle perpendicular to the
source line.

* `length`: The length of the wiggle along the line.

* `randomness`: The scale factor by which the length is
shrunken or expanded.

May return `None` if no sketch parameters were set.
"""
return self._sketch

def set_sketch_params(self, scale=None, length=None, randomness=None):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically I don't think these need to be keywords as they are always given (in the draw method). But I agree that keeping the signature consistent is useful.

"""
Sets the the sketch parameters.

Parameters
----------

scale : float, optional
The amplitude of the wiggle perpendicular to the source
line, in pixels. If scale is `None`, or not provided, no
sketch filter will be provided.

length : float, optional
The length of the wiggle along the line, in pixels
(default 128.0)

randomness : float, optional
The scale factor by which the length is shrunken or
expanded (default 16.0)
"""
if scale is None:
self._sketch = None
else:
self._sketch = (scale, length or 128.0, randomness or 16.0)


class TimerBase(object):
'''
Expand Down Expand Up @@ -1937,7 +1986,7 @@ def print_jpg(self, filename_or_obj, *args, **kwargs):

*quality*: The image quality, on a scale from 1 (worst) to
95 (best). The default is 95, if not given in the
matplotlibrc file in the savefig.jpeg_quality parameter.
matplotlibrc file in the savefig.jpeg_quality parameter.
Values above 95 should be avoided; 100 completely
disables the JPEG quantization stage.

Expand All @@ -1957,7 +2006,7 @@ def print_jpg(self, filename_or_obj, *args, **kwargs):
options = cbook.restrict_dict(kwargs, ['quality', 'optimize',
'progressive'])

if 'quality' not in options:
if 'quality' not in options:
options['quality'] = rcParams['savefig.jpeg_quality']

return image.save(filename_or_obj, format='jpeg', **options)
Expand Down
Loading
X Tutup