Skip to content

Modified scatter method to correctly recognize RGB/A values #6087

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 16 commits into from
Closed
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
Binary file added doc/_static/ggplot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/holoviews.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/seaborn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion doc/_templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,11 @@ <h1>Toolkits</h1>
including a choice of two projection and mapping toolkits <a href="http://matplotlib.org/basemap">basemap</a> and
<a href="http://scitools.org.uk/cartopy/docs/latest">cartopy</a>,
3d plotting with <a href="{{ pathto('mpl_toolkits/mplot3d/index') }}">mplot3d</a>,
axes and axis helpers in <a href="{{ pathto('mpl_toolkits/axes_grid/index') }}">axes_grid</a> and more.
axes and axis helpers in <a href="{{ pathto('mpl_toolkits/axes_grid/index') }}">axes_grid</a>,
several higher-level plotting interfaces
<a href="http://web.stanford.edu/~mwaskom/software/seaborn">seaborn</a>,
<a href="http://holoviews.org">holoviews</a>,
<a href="http://ggplot.yhathq.com">ggplot</a>, and more.
</p>

<h1>Citing matplotlib</h1>
Expand Down
2 changes: 0 additions & 2 deletions doc/_templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ <h3>{{ _('Navigation') }}</h3>

{% block relbar1 %}

<link rel="shortcut icon" href="/_static/favicon.ico">

<!-- The "Fork me on github" ribbon -->
<img style="float: right; margin-bottom: -40px; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" usemap="#ribbonmap"/>
<map name="ribbonmap">
Expand Down
2 changes: 2 additions & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@
# Output file base name for HTML help builder.
htmlhelp_basename = 'Matplotlibdoc'

# Path to favicon
html_favicon = '_static/favicon.ico'

# Options for LaTeX output
# ------------------------
Expand Down
23 changes: 23 additions & 0 deletions doc/mpl_toolkits/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,26 @@ level interface for drawing statistical graphics with matplotlib. It
aims to make visualization a central part of exploring and
understanding complex datasets.

.. image:: /_static/seaborn.png
:height: 157px

.. _toolkit_holoviews:

holoviews
=========
(*Not distributed with matplotlib*)

`holoviews <http://holoviews.org>`_ makes it easier to visualize data
interactively, especially in a `Jupyter notebook
<http://jupyter.org>`_, by providing a set of declarative
plotting objects that store your data and associated metadata. Your
data is then immediately visualizable alongside or overlaid with other
data, either statically or with automatically provided widgets for
parameter exploration.

.. image:: /_static/holoviews.png
:height: 354px

.. _toolkit_ggplot:

ggplot
Expand All @@ -181,6 +201,9 @@ ggplot
`ggplot <https://github.com/yhat/ggplot>`_ is a port of the R ggplot2
to python based on matplotlib.

.. image:: /_static/ggplot.png
:height: 195px


.. _toolkit_prettyplotlib:

Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3861,7 +3861,7 @@ def scatter(self, x, y, s=20, c=None, marker='o', cmap=None, norm=None,
# favor of mapping, not rgb or rgba.
try:
c_array = np.asanyarray(c, dtype=float)
if c_array.size == x.size:
if c_array.size == x.size and c_array.ndim == 1:
c = np.ma.ravel(c_array)
else:
# Wrong size; it must not be intended for mapping.
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def _apply_params(self, **kw):
# -> points. grab the integer from the `Text` object
# instead of saving the string representation
v = getattr(self.label1, 'get_' + k)()
setattr(self, '_' + k, v)
setattr(self, '_label' + k, v)


class XTick(Tick):
Expand Down
4 changes: 0 additions & 4 deletions lib/matplotlib/cm.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,6 @@ def to_rgba(self, x, alpha=None, bytes=False, norm=True):
if norm:
x = self.norm(x)
rgba = self.cmap(x, alpha=alpha, bytes=bytes)
# For floating-point greyscale images, we treat negative as
# transparent so we copy that over to the alpha channel
if x.ndim == 2 and x.dtype.kind == 'f':
rgba[:, :, 3][x < 0.0] = 0
return rgba

def set_array(self, A):
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ def set_linestyle(self, ls):
=========================== =================
``'-'`` or ``'solid'`` solid line
``'--'`` or ``'dashed'`` dashed line
``'-.'`` or ``'dash_dot'`` dash-dotted line
``'-.'`` or ``'dashdot'`` dash-dotted line
``':'`` or ``'dotted'`` dotted line
=========================== =================

Expand Down
30 changes: 19 additions & 11 deletions lib/matplotlib/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,20 +354,22 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
out_height = int(out_height_base)

if not unsampled:
created_rgba_mask = False

if A.ndim == 2:
A = self.norm(A)
# If the image is greyscale, convert to RGBA with the
# correct alpha channel for resizing
rgba = np.empty((A.shape[0], A.shape[1], 4), dtype=A.dtype)
rgba[..., 0:3] = np.expand_dims(A, 2)
if A.dtype.kind == 'f':
# For floating-point greyscale images, we treat negative
# numbers as transparent.

# TODO: Use np.full when we support Numpy 1.9 as a
# minimum
output = np.empty((out_height, out_width), dtype=A.dtype)
output[...] = -100.0
rgba[..., 3] = ~A.mask
else:
output = np.zeros((out_height, out_width), dtype=A.dtype)

rgba[..., 3] = np.where(A.mask, 0, np.iinfo(A.dtype).max)
A = rgba
output = np.zeros((out_height, out_width, 4), dtype=A.dtype)
alpha = 1.0
created_rgba_mask = True
elif A.ndim == 3:
# Always convert to RGBA, even if only RGB input
if A.shape[2] == 3:
Expand All @@ -388,10 +390,16 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
self.get_resample(), alpha,
self.get_filternorm() or 0.0, self.get_filterrad() or 0.0)

if created_rgba_mask:
# Convert back to a masked greyscale array so
# colormapping works correctly
output = np.ma.masked_array(
output[..., 0], output[..., 3] < 0.5)

output = self.to_rgba(output, bytes=True, norm=False)

# Apply alpha *after* if the input was greyscale
if A.ndim == 2:
# Apply alpha *after* if the input was greyscale without a mask
if A.ndim == 2 or created_rgba_mask:
alpha = self.get_alpha()
if alpha is not None and alpha != 1.0:
alpha_channel = output[:, :, 3]
Expand Down
13 changes: 11 additions & 2 deletions lib/matplotlib/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ def _auto_legend_data(self):
ax = self.parent
bboxes = []
lines = []
offsets = []

for handle in ax.lines:
assert isinstance(handle, Line2D)
Expand All @@ -755,12 +756,19 @@ def _auto_legend_data(self):
transform = handle.get_transform()
bboxes.append(handle.get_path().get_extents(transform))

for handle in ax.collections:
transform, transOffset, hoffsets, paths = handle._prepare_points()

if len(hoffsets):
for offset in transOffset.transform(hoffsets):
offsets.append(offset)

try:
vertices = np.concatenate([l.vertices for l in lines])
except ValueError:
vertices = np.array([])

return [vertices, bboxes, lines]
return [vertices, bboxes, lines, offsets]

def draw_frame(self, b):
'b is a boolean. Set draw frame to b'
Expand Down Expand Up @@ -920,7 +928,7 @@ def _find_best_position(self, width, height, renderer, consider=None):
# should always hold because function is only called internally
assert self.isaxes

verts, bboxes, lines = self._auto_legend_data()
verts, bboxes, lines, offsets = self._auto_legend_data()

bbox = Bbox.from_bounds(0, 0, width, height)
if consider is None:
Expand All @@ -939,6 +947,7 @@ def _find_best_position(self, width, height, renderer, consider=None):
# take their into account when checking vertex overlaps in
# the next line.
badness = legendBox.count_contains(verts)
badness += legendBox.count_contains(offsets)
badness += legendBox.count_overlaps(bboxes)
for line in lines:
# FIXME: the following line is ill-suited for lines
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/lines.py
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ def set_linestyle(self, ls):
=========================== =================
``'-'`` or ``'solid'`` solid line
``'--'`` or ``'dashed'`` dashed line
``'-.'`` or ``'dash_dot'`` dash-dotted line
``'-.'`` or ``'dashdot'`` dash-dotted line
``':'`` or ``'dotted'`` dotted line
``'None'`` draw nothing
``' '`` draw nothing
Expand Down
43 changes: 25 additions & 18 deletions lib/matplotlib/mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,17 @@
##############################################################################
# FONTS

def get_unicode_index(symbol):
"""get_unicode_index(symbol) -> integer
def get_unicode_index(symbol, math=True):
"""get_unicode_index(symbol, [bool]) -> integer

Return the integer index (from the Unicode table) of symbol. *symbol*
can be a single unicode character, a TeX command (i.e. r'\pi'), or a
Type1 symbol name (i.e. 'phi').
If math is False, the current symbol should be treated as a non-math symbol.
"""
# for a non-math symbol, simply return its unicode index
if not math:
return ord(symbol)
# From UTF #25: U+2212 minus sign is the preferred
# representation of the unary and binary minus sign rather than
# the ASCII-derived U+002D hyphen-minus, because minus sign is
Expand Down Expand Up @@ -438,7 +442,7 @@ def get_kern(self, font1, fontclass1, sym1, fontsize1,
"""
return 0.

def get_metrics(self, font, font_class, sym, fontsize, dpi):
def get_metrics(self, font, font_class, sym, fontsize, dpi, math=True):
"""
*font*: one of the TeX font names::

Expand All @@ -452,6 +456,8 @@ def get_metrics(self, font, font_class, sym, fontsize, dpi):

*dpi*: current dots-per-inch

*math*: whether sym is a math character

Returns an object with the following attributes:

- *advance*: The advance distance (in points) of the glyph.
Expand All @@ -466,7 +472,7 @@ def get_metrics(self, font, font_class, sym, fontsize, dpi):
the glyph. This corresponds to TeX's definition of
"height".
"""
info = self._get_info(font, font_class, sym, fontsize, dpi)
info = self._get_info(font, font_class, sym, fontsize, dpi, math)
return info.metrics

def set_canvas_size(self, w, h, d):
Expand Down Expand Up @@ -582,14 +588,14 @@ def _get_offset(self, font, glyph, fontsize, dpi):
return ((glyph.height/64.0/2.0) + (fontsize/3.0 * dpi/72.0))
return 0.

def _get_info(self, fontname, font_class, sym, fontsize, dpi):
def _get_info(self, fontname, font_class, sym, fontsize, dpi, math=True):
key = fontname, font_class, sym, fontsize, dpi
bunch = self.glyphd.get(key)
if bunch is not None:
return bunch

font, num, symbol_name, fontsize, slanted = \
self._get_glyph(fontname, font_class, sym, fontsize)
self._get_glyph(fontname, font_class, sym, fontsize, math)

font.set_size(fontsize, dpi)
glyph = font.load_char(
Expand Down Expand Up @@ -679,7 +685,7 @@ def __init__(self, *args, **kwargs):

_slanted_symbols = set(r"\int \oint".split())

def _get_glyph(self, fontname, font_class, sym, fontsize):
def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
symbol_name = None
font = None
if fontname in self.fontmap and sym in latex_to_bakoma:
Expand All @@ -699,7 +705,7 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):

if symbol_name is None:
return self._stix_fallback._get_glyph(
fontname, font_class, sym, fontsize)
fontname, font_class, sym, fontsize, math)

return font, num, symbol_name, fontsize, slanted

Expand Down Expand Up @@ -796,7 +802,7 @@ def __init__(self, *args, **kwargs):
def _map_virtual_font(self, fontname, font_class, uniindex):
return fontname, uniindex

def _get_glyph(self, fontname, font_class, sym, fontsize):
def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
found_symbol = False

if self.use_cmex:
Expand All @@ -807,7 +813,7 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):

if not found_symbol:
try:
uniindex = get_unicode_index(sym)
uniindex = get_unicode_index(sym, math)
found_symbol = True
except ValueError:
uniindex = ord('?')
Expand Down Expand Up @@ -901,11 +907,11 @@ def __init__(self, *args, **kwargs):
self.fontmap[key] = fullpath
self.fontmap[name] = fullpath

def _get_glyph(self, fontname, font_class, sym, fontsize):
def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
""" Override prime symbol to use Bakoma """
if sym == r'\prime':
return self.bakoma._get_glyph(fontname,
font_class, sym, fontsize)
font_class, sym, fontsize, math)
else:
# check whether the glyph is available in the display font
uniindex = get_unicode_index(sym)
Expand All @@ -914,10 +920,10 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):
glyphindex = font.get_char_index(uniindex)
if glyphindex != 0:
return super(DejaVuFonts, self)._get_glyph('ex',
font_class, sym, fontsize)
font_class, sym, fontsize, math)
# otherwise return regular glyph
return super(DejaVuFonts, self)._get_glyph(fontname,
font_class, sym, fontsize)
font_class, sym, fontsize, math)


class DejaVuSerifFonts(DejaVuFonts):
Expand Down Expand Up @@ -1123,7 +1129,7 @@ def _get_font(self, font):
self.fonts[cached_font.get_fontname()] = cached_font
return cached_font

def _get_info (self, fontname, font_class, sym, fontsize, dpi):
def _get_info (self, fontname, font_class, sym, fontsize, dpi, math=True):
'load the cmfont, metrics and glyph with caching'
key = fontname, sym, fontsize, dpi
tup = self.glyphd.get(key)
Expand Down Expand Up @@ -1449,14 +1455,15 @@ class Char(Node):
from width) must be converted into a :class:`Kern` node when the
:class:`Char` is added to its parent :class:`Hlist`.
"""
def __init__(self, c, state):
def __init__(self, c, state, math=True):
Node.__init__(self)
self.c = c
self.font_output = state.font_output
self.font = state.font
self.font_class = state.font_class
self.fontsize = state.fontsize
self.dpi = state.dpi
self.math = math
# The real width, height and depth will be set during the
# pack phase, after we know the real fontsize
self._update_metrics()
Expand All @@ -1466,7 +1473,7 @@ def __internal_repr__(self):

def _update_metrics(self):
metrics = self._metrics = self.font_output.get_metrics(
self.font, self.font_class, self.c, self.fontsize, self.dpi)
self.font, self.font_class, self.c, self.fontsize, self.dpi, self.math)
if self.c == ' ':
self.width = metrics.advance
else:
Expand Down Expand Up @@ -2580,7 +2587,7 @@ def math(self, s, loc, toks):
def non_math(self, s, loc, toks):
#~ print "non_math", toks
s = toks[0].replace(r'\$', '$')
symbols = [Char(c, self.get_state()) for c in s]
symbols = [Char(c, self.get_state(), math=False) for c in s]
hlist = Hlist(symbols)
# We're going into math now, so set font to 'it'
self.push_state()
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def set_linestyle(self, ls):
=========================== =================
``'-'`` or ``'solid'`` solid line
``'--'`` or ``'dashed'`` dashed line
``'-.'`` or ``'dash_dot'`` dash-dotted line
``'-.'`` or ``'dashdot'`` dash-dotted line
``':'`` or ``'dotted'`` dotted line
=========================== =================

Expand Down
Loading