123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- 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
|