208 lines
5.7 KiB
Python
208 lines
5.7 KiB
Python
import numpy as np
|
|
from io import BytesIO
|
|
import re
|
|
import tempfile
|
|
import xml.parsers.expat
|
|
|
|
import pytest
|
|
|
|
import matplotlib as mpl
|
|
from matplotlib import dviread
|
|
from matplotlib.figure import Figure
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.testing.decorators import image_comparison
|
|
|
|
|
|
needs_usetex = pytest.mark.skipif(
|
|
not mpl.checkdep_usetex(True),
|
|
reason="This test needs a TeX installation")
|
|
|
|
|
|
def test_visibility():
|
|
fig, ax = plt.subplots()
|
|
|
|
x = np.linspace(0, 4 * np.pi, 50)
|
|
y = np.sin(x)
|
|
yerr = np.ones_like(y)
|
|
|
|
a, b, c = ax.errorbar(x, y, yerr=yerr, fmt='ko')
|
|
for artist in b:
|
|
artist.set_visible(False)
|
|
|
|
fd = BytesIO()
|
|
fig.savefig(fd, format='svg')
|
|
|
|
fd.seek(0)
|
|
buf = fd.read()
|
|
fd.close()
|
|
|
|
parser = xml.parsers.expat.ParserCreate()
|
|
parser.Parse(buf) # this will raise ExpatError if the svg is invalid
|
|
|
|
|
|
@image_comparison(['fill_black_with_alpha.svg'], remove_text=True)
|
|
def test_fill_black_with_alpha():
|
|
fig = plt.figure()
|
|
ax = fig.add_subplot(1, 1, 1)
|
|
ax.scatter(x=[0, 0.1, 1], y=[0, 0, 0], c='k', alpha=0.1, s=10000)
|
|
|
|
|
|
@image_comparison(['noscale'], remove_text=True)
|
|
def test_noscale():
|
|
X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1))
|
|
Z = np.sin(Y ** 2)
|
|
|
|
fig = plt.figure()
|
|
ax = fig.add_subplot(1, 1, 1)
|
|
ax.imshow(Z, cmap='gray', interpolation='none')
|
|
|
|
|
|
def test_text_urls():
|
|
fig = plt.figure()
|
|
|
|
test_url = "http://test_text_urls.matplotlib.org"
|
|
fig.suptitle("test_text_urls", url=test_url)
|
|
|
|
fd = BytesIO()
|
|
fig.savefig(fd, format='svg')
|
|
fd.seek(0)
|
|
buf = fd.read().decode()
|
|
fd.close()
|
|
|
|
expected = '<a xlink:href="{0}">'.format(test_url)
|
|
assert expected in buf
|
|
|
|
|
|
@image_comparison(['bold_font_output.svg'])
|
|
def test_bold_font_output():
|
|
fig = plt.figure()
|
|
ax = fig.add_subplot(1, 1, 1)
|
|
ax.plot(np.arange(10), np.arange(10))
|
|
ax.set_xlabel('nonbold-xlabel')
|
|
ax.set_ylabel('bold-ylabel', fontweight='bold')
|
|
ax.set_title('bold-title', fontweight='bold')
|
|
|
|
|
|
@image_comparison(['bold_font_output_with_none_fonttype.svg'])
|
|
def test_bold_font_output_with_none_fonttype():
|
|
plt.rcParams['svg.fonttype'] = 'none'
|
|
fig = plt.figure()
|
|
ax = fig.add_subplot(1, 1, 1)
|
|
ax.plot(np.arange(10), np.arange(10))
|
|
ax.set_xlabel('nonbold-xlabel')
|
|
ax.set_ylabel('bold-ylabel', fontweight='bold')
|
|
ax.set_title('bold-title', fontweight='bold')
|
|
|
|
|
|
@needs_usetex
|
|
def test_missing_psfont(monkeypatch):
|
|
"""An error is raised if a TeX font lacks a Type-1 equivalent"""
|
|
|
|
def psfont(*args, **kwargs):
|
|
return dviread.PsFont(texname='texfont', psname='Some Font',
|
|
effects=None, encoding=None, filename=None)
|
|
|
|
monkeypatch.setattr(dviread.PsfontsMap, '__getitem__', psfont)
|
|
mpl.rc('text', usetex=True)
|
|
fig, ax = plt.subplots()
|
|
ax.text(0.5, 0.5, 'hello')
|
|
with tempfile.TemporaryFile() as tmpfile, pytest.raises(ValueError):
|
|
fig.savefig(tmpfile, format='svg')
|
|
|
|
|
|
# Use Computer Modern Sans Serif, not Helvetica (which has no \textwon).
|
|
@pytest.mark.style('default')
|
|
@needs_usetex
|
|
def test_unicode_won():
|
|
fig = Figure()
|
|
fig.text(.5, .5, r'\textwon', usetex=True)
|
|
|
|
with BytesIO() as fd:
|
|
fig.savefig(fd, format='svg')
|
|
buf = fd.getvalue().decode('ascii')
|
|
|
|
won_id = 'Computer_Modern_Sans_Serif-142'
|
|
assert re.search(r'<path d=(.|\s)*?id="{0}"/>'.format(won_id), buf)
|
|
assert re.search(r'<use[^/>]*? xlink:href="#{0}"/>'.format(won_id), buf)
|
|
|
|
|
|
def test_svgnone_with_data_coordinates():
|
|
plt.rcParams['svg.fonttype'] = 'none'
|
|
expected = 'Unlikely to appear by chance'
|
|
|
|
fig, ax = plt.subplots()
|
|
ax.text(np.datetime64('2019-06-30'), 1, expected)
|
|
ax.set_xlim(np.datetime64('2019-01-01'), np.datetime64('2019-12-31'))
|
|
ax.set_ylim(0, 2)
|
|
|
|
with BytesIO() as fd:
|
|
fig.savefig(fd, format='svg')
|
|
fd.seek(0)
|
|
buf = fd.read().decode()
|
|
|
|
assert expected in buf
|
|
|
|
|
|
def test_gid():
|
|
"""Test that object gid appears in output svg."""
|
|
from matplotlib.offsetbox import OffsetBox
|
|
from matplotlib.axis import Tick
|
|
|
|
fig = plt.figure()
|
|
|
|
ax1 = fig.add_subplot(131)
|
|
ax1.imshow([[1., 2.], [2., 3.]], aspect="auto")
|
|
ax1.scatter([1, 2, 3], [1, 2, 3], label="myscatter")
|
|
ax1.plot([2, 3, 1], label="myplot")
|
|
ax1.legend()
|
|
ax1a = ax1.twinx()
|
|
ax1a.bar([1, 2, 3], [1, 2, 3])
|
|
|
|
ax2 = fig.add_subplot(132, projection="polar")
|
|
ax2.plot([0, 1.5, 3], [1, 2, 3])
|
|
|
|
ax3 = fig.add_subplot(133, projection="3d")
|
|
ax3.plot([1, 2], [1, 2], [1, 2])
|
|
|
|
fig.canvas.draw()
|
|
|
|
gdic = {}
|
|
for idx, obj in enumerate(fig.findobj(include_self=True)):
|
|
if obj.get_visible():
|
|
gid = f"test123{obj.__class__.__name__}_{idx}"
|
|
gdic[gid] = obj
|
|
obj.set_gid(gid)
|
|
|
|
fd = BytesIO()
|
|
fig.savefig(fd, format='svg')
|
|
fd.seek(0)
|
|
buf = fd.read().decode()
|
|
fd.close()
|
|
|
|
def include(gid, obj):
|
|
# we need to exclude certain objects which will not appear in the svg
|
|
if isinstance(obj, OffsetBox):
|
|
return False
|
|
if isinstance(obj, plt.Text):
|
|
if obj.get_text() == "":
|
|
return False
|
|
elif obj.axes is None:
|
|
return False
|
|
if isinstance(obj, plt.Line2D):
|
|
if np.array(obj.get_data()).shape == (2, 1):
|
|
return False
|
|
elif not hasattr(obj, "axes") or obj.axes is None:
|
|
return False
|
|
if isinstance(obj, Tick):
|
|
loc = obj.get_loc()
|
|
if loc == 0:
|
|
return False
|
|
vi = obj.get_view_interval()
|
|
if loc < min(vi) or loc > max(vi):
|
|
return False
|
|
return True
|
|
|
|
for gid, obj in gdic.items():
|
|
if include(gid, obj):
|
|
assert gid in buf
|