Skip to content

Make colorbar compatible accepting a list of axes created via gridspec #8755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1b0ac37
Clarify how a FancyArrowPatch behaves
dstansby Jun 2, 2017
070a578
Clarify in display units
dstansby Jun 7, 2017
089818b
Allow divmod to be overridden by numpy
dstansby Jun 9, 2017
b87778e
Various cleanups to backends code.
anntzer Jun 3, 2017
40fa293
Update FreeType version in test_tightlayout4.
QuLogic Jun 2, 2017
c0ecc7d
Add a unique number to any renderer hash keys.
QuLogic Jun 3, 2017
df672df
Update tests that are marked flaky.
QuLogic Jun 3, 2017
9bf168f
Use itertools.count for renderer unique ID.
QuLogic Jun 4, 2017
454e9d6
Simplify cla sharex/sharey code; alternative to #8710
efiring Jun 4, 2017
edfdc53
MNT: colorbar accept numpy array input (#8739)
jklymak Jun 12, 2017
2284e98
Changed normalization in _spectral_helper() to obtain conistent scali…
DietBru May 6, 2017
234089d
Added note to api_changes
DietBru Jun 11, 2017
a62d3e3
Fix contour colour level determination
dstansby Jun 9, 2017
03c00d7
Correct contour level test
dstansby Jun 9, 2017
65f3906
sort input files
bmwiedemann Jun 12, 2017
62aa006
First pass; seems to work. More testing needed
jklymak Jun 13, 2017
fb3f419
First pass; seems to work. More testing needed
jklymak Jun 13, 2017
89857c7
First pass; seems to work. More testing needed
jklymak Jun 13, 2017
c68a411
First pass; seems to work. More testing needed
jklymak Jun 13, 2017
031d356
First change
jklymak Jun 13, 2017
1c5a14e
Aded comments and cleaned up
jklymak Jun 13, 2017
12737f5
Aded comments and cleaned up
jklymak Jun 13, 2017
600253e
Colormap that handles gridspec
jklymak Jun 13, 2017
fd388aa
Colormap that handles gridspec
jklymak Jun 13, 2017
262fa33
Colormap that handles gridspec
jklymak Jun 13, 2017
37998b4
Fixed subplotspec geometry having None
jklymak Jun 13, 2017
d9b49b5
Fixed subplotspec geometry having None, PEP8 errors
jklymak Jun 13, 2017
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
11 changes: 11 additions & 0 deletions doc/api/api_changes/2017-06-03-ES_unique_renderer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Unique identifier added to `RendererBase` classes
`````````````````````````````````````````````````

Since ``id()`` is not guaranteed to be unique between objects that exist at
different times, a new private property ``_uid`` has been added to
`RendererBase` which is used along with the renderer's ``id()`` to cache
certain expensive operations.

If a custom renderer does not subclass `RendererBase` or `MixedModeRenderer`,
it is not required to implement this ``_uid`` property, but this may produce
incorrect behavior when the renderers' ``id()`` clashes.
31 changes: 31 additions & 0 deletions doc/api/api_changes/2017-06-11-DB_magnitude_spectrum.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Correct scaling of :func:`magnitude_spectrum()`
```````````````````````````````````````````````

The functions :func:`matplotlib.mlab.magnitude_spectrum()` and :func:`matplotlib.pyplot.magnitude_spectrum()` implicitly assumed the sum
of windowing function values to be one. In Matplotlib and Numpy the
standard windowing functions are scaled to have maximum value of one,
which usually results in a sum of the order of n/2 for a n-point
signal. Thus the amplitude scaling :func:`magnitude_spectrum()` was
off by that amount when using standard windowing functions (`Bug 8417
<https://github.com/matplotlib/matplotlib/issues/8417>`_ ). Now the
behavior is consistent with :func:`matplotlib.pyplot.psd()` and
:func:`scipy.signal.welch()`. The following example demonstrates the
new and old scaling::

import matplotlib.pyplot as plt
import numpy as np

tau, n = 10, 1024 # 10 second signal with 1024 points
T = tau/n # sampling interval
t = np.arange(n)*T

a = 4 # amplitude
x = a*np.sin(40*np.pi*t) # 20 Hz sine with amplitude a

# New correct behavior: Amplitude at 20 Hz is a/2
plt.magnitude_spectrum(x, Fs=1/T, sides='onesided', scale='linear')

# Original behavior: Amplitude at 20 Hz is (a/2)*(n/2) for a Hanning window
w = np.hanning(n) # default window is a Hanning window
plt.magnitude_spectrum(x*np.sum(w), Fs=1/T, sides='onesided', scale='linear')

3 changes: 1 addition & 2 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6666,8 +6666,7 @@ def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,

scale : [ 'default' | 'linear' | 'dB' ]
The scaling of the values in the *spec*. 'linear' is no scaling.
'dB' returns the values in dB scale. When *mode* is 'density',
this is dB power (10 * log10). Otherwise this is dB amplitude
'dB' returns the values in dB scale, i.e., the dB amplitude
(20 * log10). 'default' is 'linear'.

Fc : integer
Expand Down
34 changes: 4 additions & 30 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,21 +980,8 @@ def cla(self):
self.xaxis.minor = self._sharex.xaxis.minor
x0, x1 = self._sharex.get_xlim()
self.set_xlim(x0, x1, emit=False, auto=None)

# Save the current formatter/locator so we don't lose it
majf = self._sharex.xaxis.get_major_formatter()
minf = self._sharex.xaxis.get_minor_formatter()
majl = self._sharex.xaxis.get_major_locator()
minl = self._sharex.xaxis.get_minor_locator()

# This overwrites the current formatter/locator
self.xaxis._set_scale(self._sharex.xaxis.get_scale())

# Reset the formatter/locator
self.xaxis.set_major_formatter(majf)
self.xaxis.set_minor_formatter(minf)
self.xaxis.set_major_locator(majl)
self.xaxis.set_minor_locator(minl)
self.xaxis._scale = mscale.scale_factory(
self._sharex.xaxis.get_scale(), self.xaxis)
else:
self.xaxis._set_scale('linear')
try:
Expand All @@ -1007,21 +994,8 @@ def cla(self):
self.yaxis.minor = self._sharey.yaxis.minor
y0, y1 = self._sharey.get_ylim()
self.set_ylim(y0, y1, emit=False, auto=None)

# Save the current formatter/locator so we don't lose it
majf = self._sharey.yaxis.get_major_formatter()
minf = self._sharey.yaxis.get_minor_formatter()
majl = self._sharey.yaxis.get_major_locator()
minl = self._sharey.yaxis.get_minor_locator()

# This overwrites the current formatter/locator
self.yaxis._set_scale(self._sharey.yaxis.get_scale())

# Reset the formatter/locator
self.yaxis.set_major_formatter(majf)
self.yaxis.set_minor_formatter(minf)
self.yaxis.set_major_locator(majl)
self.yaxis.set_minor_locator(minl)
self.yaxis._scale = mscale.scale_factory(
self._sharey.yaxis.get_scale(), self.yaxis)
else:
self.yaxis._set_scale('linear')
try:
Expand Down
11 changes: 11 additions & 0 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from contextlib import contextmanager
import importlib
import io
import itertools
import os
import sys
import time
Expand Down Expand Up @@ -100,6 +101,12 @@
}


# Used to ensure that caching based on renderer id() is unique without being as
# expensive as a real UUID. 0 is used for renderers that don't derive from
# here, so start at 1.
_unique_renderer_id = itertools.count(1)


def register_backend(format, backend, description=None):
"""
Register a backend for saving to a given file format.
Expand Down Expand Up @@ -212,6 +219,10 @@ class RendererBase(object):

"""
def __init__(self):
# A lightweight id for unique-ification purposes. Along with id(self),
# the combination should be unique enough to use as part of a cache key.
self._uid = next(_unique_renderer_id)

self._texmanager = None

self._text2path = textpath.TextToPath()
Expand Down
34 changes: 0 additions & 34 deletions lib/matplotlib/backends/backend_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,18 @@ class RendererAgg(RendererBase):

lock = threading.RLock()
def __init__(self, width, height, dpi):
if __debug__: verbose.report('RendererAgg.__init__', 'debug-annoying')
RendererBase.__init__(self)

self.dpi = dpi
self.width = width
self.height = height
if __debug__: verbose.report('RendererAgg.__init__ width=%s, height=%s'%(width, height), 'debug-annoying')
self._renderer = _RendererAgg(int(width), int(height), dpi, debug=False)
self._filter_renderers = []

if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
'debug-annoying')

self._update_methods()
self.mathtext_parser = MathTextParser('Agg')

self.bbox = Bbox.from_bounds(0, 0, self.width, self.height)
if __debug__: verbose.report('RendererAgg.__init__ done',
'debug-annoying')

def __getstate__(self):
# We only want to preserve the init keywords of the Renderer.
Expand Down Expand Up @@ -178,8 +171,6 @@ def draw_mathtext(self, gc, x, y, s, prop, angle):
"""
Draw the math text using matplotlib.mathtext
"""
if __debug__: verbose.report('RendererAgg.draw_mathtext',
'debug-annoying')
ox, oy, width, height, descent, font_image, used_characters = \
self.mathtext_parser.parse(s, self.dpi, prop)

Expand All @@ -193,8 +184,6 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
"""
Render the text
"""
if __debug__: verbose.report('RendererAgg.draw_text', 'debug-annoying')

if ismath:
return self.draw_mathtext(gc, x, y, s, prop, angle)

Expand Down Expand Up @@ -279,9 +268,6 @@ def _get_agg_font(self, prop):
"""
Get the font for text instance t, cacheing for efficiency
"""
if __debug__: verbose.report('RendererAgg._get_agg_font',
'debug-annoying')

fname = findfont(prop)
font = get_font(
fname,
Expand All @@ -298,23 +284,15 @@ def points_to_pixels(self, points):
convert point measures to pixes using dpi and the pixels per
inch of the display
"""
if __debug__: verbose.report('RendererAgg.points_to_pixels',
'debug-annoying')
return points*self.dpi/72.0

def tostring_rgb(self):
if __debug__: verbose.report('RendererAgg.tostring_rgb',
'debug-annoying')
return self._renderer.tostring_rgb()

def tostring_argb(self):
if __debug__: verbose.report('RendererAgg.tostring_argb',
'debug-annoying')
return self._renderer.tostring_argb()

def buffer_rgba(self):
if __debug__: verbose.report('RendererAgg.buffer_rgba',
'debug-annoying')
return self._renderer.buffer_rgba()

def clear(self):
Expand Down Expand Up @@ -423,10 +401,6 @@ def new_figure_manager(num, *args, **kwargs):
"""
Create a new figure manager instance
"""
if __debug__: verbose.report('backend_agg.new_figure_manager',
'debug-annoying')


FigureClass = kwargs.pop('FigureClass', Figure)
thisFig = FigureClass(*args, **kwargs)
return new_figure_manager_given_figure(num, thisFig)
Expand Down Expand Up @@ -465,8 +439,6 @@ def draw(self):
"""
Draw the figure using the renderer
"""
if __debug__: verbose.report('FigureCanvasAgg.draw', 'debug-annoying')

self.renderer = self.get_renderer(cleared=True)
# acquire a lock on the shared font cache
RendererAgg.lock.acquire()
Expand Down Expand Up @@ -500,8 +472,6 @@ def tostring_rgb(self):
-------
bytes
'''
if __debug__: verbose.report('FigureCanvasAgg.tostring_rgb',
'debug-annoying')
return self.renderer.tostring_rgb()

def tostring_argb(self):
Expand All @@ -515,8 +485,6 @@ def tostring_argb(self):
bytes

'''
if __debug__: verbose.report('FigureCanvasAgg.tostring_argb',
'debug-annoying')
return self.renderer.tostring_argb()

def buffer_rgba(self):
Expand All @@ -529,8 +497,6 @@ def buffer_rgba(self):
-------
bytes
'''
if __debug__: verbose.report('FigureCanvasAgg.buffer_rgba',
'debug-annoying')
return self.renderer.buffer_rgba()

def print_raw(self, filename_or_obj, *args, **kwargs):
Expand Down
18 changes: 0 additions & 18 deletions lib/matplotlib/backends/backend_cairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@

import numpy as np

def _fn_name(): return sys._getframe(1).f_code.co_name

try:
import cairocffi as cairo
except ImportError:
Expand Down Expand Up @@ -58,9 +56,6 @@ def _fn_name(): return sys._getframe(1).f_code.co_name
from matplotlib.transforms import Bbox, Affine2D
from matplotlib.font_manager import ttfFontProperty

_debug = False
#_debug = True

# Image::color_conv(format) for draw_image()
if sys.byteorder == 'little':
BYTE_FORMAT = 0 # BGRA
Expand Down Expand Up @@ -114,7 +109,6 @@ class RendererCairo(RendererBase):
def __init__(self, dpi):
"""
"""
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
self.dpi = dpi
self.gc = GraphicsContextCairo (renderer=self)
self.text_ctx = cairo.Context (
Expand Down Expand Up @@ -227,8 +221,6 @@ def draw_markers(self, gc, marker_path, marker_trans, path, transform, rgbFace=N

def draw_image(self, gc, x, y, im):
# bbox - not currently used
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))

if sys.byteorder == 'little':
im = im[:, :, (2, 1, 0, 3)]
else:
Expand Down Expand Up @@ -266,8 +258,6 @@ def draw_image(self, gc, x, y, im):
def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
# Note: x,y are device/display coords, not user-coords, unlike other
# draw_* methods
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))

if ismath:
self._draw_mathtext(gc, x, y, s, prop, angle)

Expand Down Expand Up @@ -297,8 +287,6 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
ctx.restore()

def _draw_mathtext(self, gc, x, y, s, prop, angle):
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))

ctx = gc.ctx
width, height, descent, glyphs, rects = self.mathtext_parser.parse(
s, self.dpi, prop)
Expand Down Expand Up @@ -335,19 +323,16 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle):


def flipy(self):
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
return True
#return False # tried - all draw objects ok except text (and images?)
# which comes out mirrored!


def get_canvas_width_height(self):
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
return self.width, self.height


def get_text_width_height_descent(self, s, prop, ismath):
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
if ismath:
width, height, descent, fonts, used_characters = self.mathtext_parser.parse(
s, self.dpi, prop)
Expand Down Expand Up @@ -376,15 +361,13 @@ def get_text_width_height_descent(self, s, prop, ismath):


def new_gc(self):
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
self.gc.ctx.save()
self.gc._alpha = 1.0
self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
return self.gc


def points_to_pixels(self, points):
if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
return points/72.0 * self.dpi


Expand Down Expand Up @@ -488,7 +471,6 @@ def new_figure_manager(num, *args, **kwargs): # called by backends/__init__.py
"""
Create a new figure manager instance
"""
if _debug: print('%s()' % (_fn_name()))
FigureClass = kwargs.pop('FigureClass', Figure)
thisFig = FigureClass(*args, **kwargs)
return new_figure_manager_given_figure(num, thisFig)
Expand Down
6 changes: 2 additions & 4 deletions lib/matplotlib/backends/backend_gdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import os
import sys
import warnings
def fn_name(): return sys._getframe(1).f_code.co_name

import gobject
import gtk; gdk = gtk.gdk
Expand All @@ -24,16 +23,15 @@ def fn_name(): return sys._getframe(1).f_code.co_name
import matplotlib
from matplotlib import rcParams
from matplotlib._pylab_helpers import Gcf
from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \
FigureManagerBase, FigureCanvasBase
from matplotlib.backend_bases import (
RendererBase, GraphicsContextBase, FigureManagerBase, FigureCanvasBase)
from matplotlib.cbook import restrict_dict, warn_deprecated
from matplotlib.figure import Figure
from matplotlib.mathtext import MathTextParser
from matplotlib.transforms import Affine2D
from matplotlib.backends._backend_gdk import pixbuf_get_pixels_array

backend_version = "%d.%d.%d" % gtk.pygtk_version
_debug = False

# Image formats that this backend supports - for FileChooser and print_figure()
IMAGE_FORMAT = sorted(['bmp', 'eps', 'jpg', 'png', 'ps', 'svg']) # 'raw', 'rgb'
Expand Down
Loading