Skip to content

None linestyle fix #5695

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 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
afd3afb
Build API documentation for mpl_toolkit.axes_grid1.inset_locator
sargas Jul 30, 2015
6bc091c
Add documention for inset_locator.mark_inset in axes_grid1
sargas Jul 30, 2015
281be93
Add documention to axis_grid1.inset_locator.zoomed_insert-axes
sargas Jul 31, 2015
a8f5eb6
Add documentation for axis_grid1.inset_locator.inset_axis
sargas Jul 31, 2015
748fff8
Add documentation for axis_grid1.inset_locator.InsetPosition
sargas Jul 31, 2015
2086399
Fix up imports in axis_grid1.inset_locator
sargas Jul 31, 2015
4c7abe5
Simplify axes_grid1's AnchoredLocatorBase subclasses.
sargas Aug 3, 2015
b857f71
Add docstring for axes_grid1.inset_locator.BboxPatch
sargas Aug 4, 2015
9c0cff1
Add documentation for axes_grid1.inset_locator.BboxConnector
sargas Aug 4, 2015
0898052
Add documentation for axes_grid1.inset_locator.BboxConnectorPatch
sargas Aug 4, 2015
e499425
Add module doc for axes_grid1.inset_locator
sargas Aug 4, 2015
a55250f
Move class docstrings in axes_grid1.inset_locator to constructors
sargas Aug 5, 2015
e6181de
Reform kwarg documentation in axes_grid1.inset_locator
sargas Nov 18, 2015
9a0afe3
qt: raise each new window
efiring Nov 24, 2015
7820787
Remove get tests requires
jenshnielsen Nov 8, 2015
1c5c21c
Change setup.py test to a noop telling users to run tests.py
jenshnielsen Nov 8, 2015
d9caef3
Clarifty how to install test dependencies
jenshnielsen Nov 8, 2015
7e3ef7d
FIX: formatting in LogFormatterExponent
tacaswell Dec 1, 2015
7566447
MNT: clean up exponents in simpler way
tacaswell Dec 1, 2015
f9c8aa1
TST: shotgun testing of LogFormatter.pprint_val
tacaswell Dec 1, 2015
41afb05
Update banner logo on main website
mdboom Dec 10, 2015
d981e2b
Nicer axes names in selector for figure options.
anntzer Dec 13, 2015
36ce4a7
Fix #5670. No double endpoints in Path.to_polygon
mdboom Dec 14, 2015
66a4f88
Fix unit tests
mdboom Dec 14, 2015
bf230fd
PEP8
mdboom Dec 14, 2015
c6dda2d
Merge pull request #5594 from tacaswell/fix_logformatterexponent
mdboom Dec 14, 2015
0d47b5b
Fix errorbar extension arrows
mdboom Nov 25, 2015
2b34996
PEP8
mdboom Nov 30, 2015
5904e2f
Merge pull request #5553 from efiring/qtontop
mdboom Dec 14, 2015
43c66e1
Fix #5573: Use SVG in docs
mdboom Dec 14, 2015
a82ca89
Merge pull request #5672 from mdboom/double-endpoints
tacaswell Dec 15, 2015
ef9bbe2
Merge pull request #5667 from anntzer/friendlier-axes-selector
tacaswell Dec 15, 2015
ca93a06
Merge pull request #5653 from mdboom/update-logo
tacaswell Dec 15, 2015
957cc90
Merge pull request #5586 from mdboom/errorbar-extension-arrows
jenshnielsen Dec 15, 2015
3baf47f
Merge branch 'v2.0.x'
mdboom Dec 15, 2015
e789a70
Merge pull request #5434 from jenshnielsen/nosetuptest
tacaswell Dec 15, 2015
f6b15c5
Fix format parsing
mdboom Dec 15, 2015
4573e1e
Merge pull request #4864 from sargas/document_inset_locator
tacaswell Dec 16, 2015
838fa1f
Merge pull request #5677 from mdboom/docs-svg
tacaswell Dec 16, 2015
e45e946
Set image cmap from figure options.
anntzer Nov 12, 2015
590f042
Merge pull request #5469 from anntzer/image-options
mdboom Dec 16, 2015
a9f5070
Improved documentation for FuncFormatter formatter class
cimarronm Dec 17, 2015
23bc09d
Merge pull request #5688 from cimarronm/FuncFormatterDoc
tacaswell Dec 17, 2015
9f6bb90
Merge branch 'v2.0.x'
mdboom Dec 17, 2015
fda2e3e
Patch now support the 'None' linestyle
Rezangyal Dec 19, 2015
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: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
# Plot directive configuration
# ----------------------------

plot_formats = [('png', 80), ('hires.png', 200), ('pdf', 50)]
plot_formats = [('svg', 72), ('png', 80)]

# Subdirectories in 'examples/' directory of package and titles for gallery
mpl_example_sections = (
Expand Down
2 changes: 2 additions & 0 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,8 @@ def add_image(self, image):
Returns the image.
"""
self._set_artist_props(image)
if not image.get_label():
image.set_label('_image%d' % len(self.images))
self.images.append(image)
image._remove_method = lambda h: self.images.remove(h)
return image
Expand Down
25 changes: 7 additions & 18 deletions lib/matplotlib/backends/backend_qt5.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ def _init_toolbar(self):
if figureoptions is not None:
a = self.addAction(self._icon("qt4_editor_options.png"),
'Customize', self.edit_parameters)
a.setToolTip('Edit curves line and axes parameters')
a.setToolTip('Edit axis, curve and image parameters')

self.buttons = {}

Expand Down Expand Up @@ -619,23 +619,12 @@ def edit_parameters(self):
else:
titles = []
for axes in allaxes:
title = axes.get_title()
ylabel = axes.get_ylabel()
label = axes.get_label()
if title:
fmt = "%(title)s"
if ylabel:
fmt += ": %(ylabel)s"
fmt += " (%(axes_repr)s)"
elif ylabel:
fmt = "%(axes_repr)s (%(ylabel)s)"
elif label:
fmt = "%(axes_repr)s (%(label)s)"
else:
fmt = "%(axes_repr)s"
titles.append(fmt % dict(title=title,
ylabel=ylabel, label=label,
axes_repr=repr(axes)))
name = (axes.get_title() or
" - ".join(filter(None, [axes.get_xlabel(),
axes.get_ylabel()])) or
"<anonymous {} (id: {:#x})>".format(
type(axes).__name__, id(axes)))
titles.append(name)
item, ok = QtWidgets.QInputDialog.getItem(
self.parent, 'Customize', 'Select axes:', titles, 0, False)
if ok:
Expand Down
198 changes: 112 additions & 86 deletions lib/matplotlib/backends/qt_editor/figureoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import matplotlib.backends.qt_editor.formlayout as formlayout
from matplotlib.backends.qt_compat import QtGui
from matplotlib import markers
from matplotlib import cm, markers
from matplotlib.colors import colorConverter, rgb2hex


Expand All @@ -43,8 +43,6 @@ def figure_edit(axes, parent=None):
"""Edit matplotlib figure options"""
sep = (None, None) # separator

has_curve = len(axes.get_lines()) > 0

# Get / General
xmin, xmax = map(float, axes.get_xlim())
ymin, ymax = map(float, axes.get_ylim())
Expand All @@ -69,79 +67,103 @@ def figure_edit(axes, parent=None):
xunits = axes.xaxis.get_units()
yunits = axes.yaxis.get_units()

if has_curve:
# Get / Curves
linedict = {}
for line in axes.get_lines():
label = line.get_label()
if label == '_nolegend_':
continue
linedict[label] = line
curves = []

def prepare_data(d, init):
"""Prepare entry for FormLayout.

`d` is a mapping of shorthands to style names (a single style may
have multiple shorthands, in particular the shorthands `None`,
`"None"`, `"none"` and `""` are synonyms); `init` is one shorthand
of the initial style.

This function returns an list suitable for initializing a
FormLayout combobox, namely `[initial_name, (shorthand,
style_name), (shorthand, style_name), ...]`.
"""
# Drop duplicate shorthands from dict (by overwriting them during
# the dict comprehension).
name2short = {name: short for short, name in d.items()}
# Convert back to {shorthand: name}.
short2name = {short: name for name, short in name2short.items()}
# Find the kept shorthand for the style specified by init.
canonical_init = name2short[d[init]]
# Sort by representation and prepend the initial value.
return ([canonical_init] +
sorted(short2name.items(),
key=lambda short_and_name: short_and_name[1]))

curvelabels = sorted(linedict.keys())
for label in curvelabels:
line = linedict[label]
color = rgb2hex(colorConverter.to_rgb(line.get_color()))
ec = rgb2hex(colorConverter.to_rgb(line.get_markeredgecolor()))
fc = rgb2hex(colorConverter.to_rgb(line.get_markerfacecolor()))
curvedata = [
('Label', label),
sep,
(None, '<b>Line</b>'),
('Line Style', prepare_data(LINESTYLES, line.get_linestyle())),
('Draw Style', prepare_data(DRAWSTYLES, line.get_drawstyle())),
('Width', line.get_linewidth()),
('Color', color),
sep,
(None, '<b>Marker</b>'),
('Style', prepare_data(MARKERS, line.get_marker())),
('Size', line.get_markersize()),
('Facecolor', fc),
('Edgecolor', ec)]
curves.append([curvedata, label, ""])

# make sure that there is at least one displayed curve
has_curve = bool(curves)
# Get / Curves
linedict = {}
for line in axes.get_lines():
label = line.get_label()
if label == '_nolegend_':
continue
linedict[label] = line
curves = []

def prepare_data(d, init):
"""Prepare entry for FormLayout.

`d` is a mapping of shorthands to style names (a single style may
have multiple shorthands, in particular the shorthands `None`,
`"None"`, `"none"` and `""` are synonyms); `init` is one shorthand
of the initial style.

This function returns an list suitable for initializing a
FormLayout combobox, namely `[initial_name, (shorthand,
style_name), (shorthand, style_name), ...]`.
"""
# Drop duplicate shorthands from dict (by overwriting them during
# the dict comprehension).
name2short = {name: short for short, name in d.items()}
# Convert back to {shorthand: name}.
short2name = {short: name for name, short in name2short.items()}
# Find the kept shorthand for the style specified by init.
canonical_init = name2short[d[init]]
# Sort by representation and prepend the initial value.
return ([canonical_init] +
sorted(short2name.items(),
key=lambda short_and_name: short_and_name[1]))

curvelabels = sorted(linedict.keys())
for label in curvelabels:
line = linedict[label]
color = rgb2hex(colorConverter.to_rgb(line.get_color()))
ec = rgb2hex(colorConverter.to_rgb(line.get_markeredgecolor()))
fc = rgb2hex(colorConverter.to_rgb(line.get_markerfacecolor()))
curvedata = [
('Label', label),
sep,
(None, '<b>Line</b>'),
('Line Style', prepare_data(LINESTYLES, line.get_linestyle())),
('Draw Style', prepare_data(DRAWSTYLES, line.get_drawstyle())),
('Width', line.get_linewidth()),
('Color', color),
sep,
(None, '<b>Marker</b>'),
('Style', prepare_data(MARKERS, line.get_marker())),
('Size', line.get_markersize()),
('Facecolor', fc),
('Edgecolor', ec)]
curves.append([curvedata, label, ""])
# Is there a curve displayed?
has_curve = bool(curves)

# Get / Images
imagedict = {}
for image in axes.get_images():
label = image.get_label()
if label == '_nolegend_':
continue
imagedict[label] = image
imagelabels = sorted(imagedict)
images = []
cmaps = [(cmap, name) for name, cmap in sorted(cm.cmap_d.items())]
for label in imagelabels:
image = imagedict[label]
cmap = image.get_cmap()
if cmap not in cm.cmap_d:
cmaps = [(cmap, cmap.name)] + cmaps
imagedata = [
('Label', label),
('Colormap', [cmap.name] + cmaps)
]
images.append([imagedata, label, ""])
# Is there an image displayed?
has_image = bool(images)

datalist = [(general, "Axes", "")]
if has_curve:
if curves:
datalist.append((curves, "Curves", ""))
if images:
datalist.append((images, "Images", ""))

def apply_callback(data):
"""This function will be called to apply changes"""
if has_curve:
general, curves = data
else:
general, = data
general = data.pop(0)
curves = data.pop(0) if has_curve else []
images = data.pop(0) if has_image else []
if data:
raise ValueError("Unexpected field")

# Set / General
title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale, \
generate_legend = general
(title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale,
generate_legend) = general
axes.set_xscale(xscale)
axes.set_yscale(yscale)
axes.set_title(title)
Expand All @@ -158,26 +180,30 @@ def apply_callback(data):
axes.xaxis._update_axisinfo()
axes.yaxis._update_axisinfo()

if has_curve:
# Set / Curves
for index, curve in enumerate(curves):
line = linedict[curvelabels[index]]
label, linestyle, drawstyle, linewidth, color, \
marker, markersize, markerfacecolor, markeredgecolor \
= curve
line.set_label(label)
line.set_linestyle(linestyle)
line.set_drawstyle(drawstyle)
line.set_linewidth(linewidth)
line.set_color(color)
if marker is not 'none':
line.set_marker(marker)
line.set_markersize(markersize)
line.set_markerfacecolor(markerfacecolor)
line.set_markeredgecolor(markeredgecolor)
# Set / Curves
for index, curve in enumerate(curves):
line = linedict[curvelabels[index]]
(label, linestyle, drawstyle, linewidth, color, marker, markersize,
markerfacecolor, markeredgecolor) = curve
line.set_label(label)
line.set_linestyle(linestyle)
line.set_drawstyle(drawstyle)
line.set_linewidth(linewidth)
line.set_color(color)
if marker is not 'none':
line.set_marker(marker)
line.set_markersize(markersize)
line.set_markerfacecolor(markerfacecolor)
line.set_markeredgecolor(markeredgecolor)

# Set / Images
for index, image_settings in enumerate(images):
image = imagedict[imagelabels[index]]
label, cmap = image_settings
image.set_label(label)
image.set_cmap(cm.get_cmap(cmap))

# re-generate legend, if checkbox is checked

if generate_legend:
draggable = None
ncol = None
Expand Down
13 changes: 8 additions & 5 deletions lib/matplotlib/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,11 +499,14 @@ def draw(self, renderer):

gc.set_foreground(self._edgecolor, isRGBA=True)

lw = self._linewidth
if self._edgecolor[3] == 0:
lw = 0
gc.set_linewidth(lw)
gc.set_linestyle(self._linestyle)
if (self._edgecolor[3] == 0 or
self._linestyle in {'none', 'None', ' ', '', None}):
# (some?) renderers expect this as no-edge signal
gc.set_linewidth(0.0)
else:
gc.set_linewidth(self._linewidth)
gc.set_linestyle(self._linestyle)

gc.set_capstyle(self._capstyle)
gc.set_joinstyle(self._joinstyle)

Expand Down
35 changes: 21 additions & 14 deletions lib/matplotlib/sphinxext/plot_directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def remove_coding(text):
{% endif %}

{% for img in images %}
.. figure:: {{ build_dir }}/{{ img.basename }}.png
.. figure:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
{% for option in options -%}
{{ option }}
{% endfor %}
Expand Down Expand Up @@ -537,17 +537,7 @@ def clear_state(plot_rcparams, close=True):
matplotlib.rcParams.update(plot_rcparams)


def render_figures(code, code_path, output_dir, output_base, context,
function_name, config, context_reset=False,
close_figs=False):
"""
Run a pyplot script and save the low and high res PNGs and a PDF
in *output_dir*.

Save the images under *output_dir* with file names derived from
*output_base*
"""
# -- Parse format list
def get_plot_formats(config):
default_dpi = {'png': 80, 'hires.png': 200, 'pdf': 200}
formats = []
plot_formats = config.plot_formats
Expand All @@ -559,14 +549,27 @@ def render_figures(code, code_path, output_dir, output_base, context,
for fmt in plot_formats:
if isinstance(fmt, six.string_types):
if ':' in fmt:
suffix,dpi = fmt.split(':')
suffix, dpi = fmt.split(':')
formats.append((str(suffix), int(dpi)))
else:
formats.append((fmt, default_dpi.get(fmt, 80)))
elif type(fmt) in (tuple, list) and len(fmt)==2:
elif type(fmt) in (tuple, list) and len(fmt) == 2:
formats.append((str(fmt[0]), int(fmt[1])))
else:
raise PlotError('invalid image format "%r" in plot_formats' % fmt)
return formats


def render_figures(code, code_path, output_dir, output_base, context,
function_name, config, context_reset=False,
close_figs=False):
"""
Run a pyplot script and save the images in *output_dir*.

Save the images under *output_dir* with file names derived from
*output_base*
"""
formats = get_plot_formats(config)

# -- Try to determine if all images already exist

Expand Down Expand Up @@ -666,6 +669,9 @@ def run(arguments, content, options, state_machine, state, lineno):
config = document.settings.env.config
nofigs = 'nofigs' in options

formats = get_plot_formats(config)
default_fmt = formats[0][0]

options.setdefault('include-source', config.plot_include_source)
keep_context = 'context' in options
context_opt = None if not keep_context else options['context']
Expand Down Expand Up @@ -814,6 +820,7 @@ def run(arguments, content, options, state_machine, state, lineno):

result = format_template(
config.plot_template or TEMPLATE,
default_fmt=default_fmt,
dest_dir=dest_dir_link,
build_dir=build_dir_link,
source_link=src_link,
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/textpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
1094995778)]:
try:
font.select_charmap(charmap_code)
except ValueError:
except (ValueError, RuntimeError):
pass
else:
break
Expand Down
Loading