FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Large TrueType font does not render correctly when saving in .pdf · Issue #7937 · matplotlib/matplotlib · GitHub

Repository navigation

Large TrueType font does not render correctly when saving in .pdf #7937

Closed

Description

Bug summary

Large TrueType serif font does not render correctly when saving in .pdf

Interestingly, the bug does not happen when:

  • saving in .png
  • using default font size
  • using sans-serif font
  • using type 3 font

Code for reproduction

import matplotlib as mpl
import matplotlib.pyplot as plt

for param in [3, 42]:
    mpl.rcParams['pdf.fonttype'] = param
    mpl.rcParams["font.family"] = "serif"
    mpl.rcParams["font.size"] = 20

    fig = plt.figure()
    plt.plot([0, 1])
    plt.title('This is the title')

    fig.savefig('save_%d.pdf' % param)
    plt.close(fig)

Actual outcome
save_42.pdf

Expected outcome
save_3.pdf

Matplotlib version

Matplotlib 2.0.0 installed with conda (same behavior with pip)

System version
Linux-3.16.0-4-amd64-x86_64-with-debian-8.7
Python 3.5.2 |Continuum Analytics, Inc.| (default, Jul 2 2016, 17:53:06)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]

Activity

  1. added this to the milestone on Jan 24, 2017
  2. afvincent commented on Jan 24, 2017

    Contributor

    Hey Tom, thanks for the bug report! Are you totally certain the bug does not exist with type 42 sans-serif fonts? Because I also have a weird letter spacing with those fonts, as well as with the serif ones. For example,

    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    plt.style.use('default')
    
    for fam, ft in [('sans', 3), ('sans', 42), ('serif', 3), ('serif', 42)]:
    
        plt.rcParams['pdf.fonttype'] = ft  # in {3, 42}
        plt.rcParams['font.family'] = fam  # in {'serif', 'sans'}
        plt.rcParams['font.size'] = 20
    
        fig_label = "{fam}_T{ft}".format(fam=plt.rcParams['font.family'][0],
                                         ft=plt.rcParams['pdf.fonttype'])
        fig, ax = plt.subplots(num=fig_label)
        ax.plot([0, 1])
        ax.set_xlabel("mpl " + mpl.__version__, fontsize=10)
        ax.set_title("This is the title")
    
        fig.savefig(fig.get_label() + ".pdf")

    produces weird outputs with both type 42 font families
    sans_T42.pdf
    serif_T42.pdf
    while the outputs are OK with both type 3 font families:
    sans_T3.pdf
    serif_T3.pdf

    Setup:
    matplotlib from master ('2.0.0rc2.post3092+g2374c9b')
    CentOS 7 (Linux 3.10.0-327.3.1.el7.x86_64)
    Python 2.7.11 (from Continuum Analytics, Inc.)

  3. TomDLT commented on Jan 26, 2017

    ContributorAuthor

    Indeed you are right, the weird spacing happens also with sans-serif font, I overlooked this test.

  4. changed the title [-]Large TrueType serif font does not render correctly when saving in .pdf[/-] [+]Large TrueType font does not render correctly when saving in .pdf[/+] on Jan 26, 2017
  5. afvincent commented on Jan 27, 2017

    Contributor

    I wonder if the weird spacing with type 42 fonts isn't a bigger issue than first thought. Running

    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    
    def plot_font_grade(family, fonttype):
        plt.style.use('default')  # just to be sure
    
        plt.rcParams['pdf.fonttype'] = fonttype  # in {3, 42}
        plt.rcParams['font.family'] = family  # in {'serif', 'sans'}
    
        fig_label = "{fam}_T{ft}_grade".format(fam=plt.rcParams['font.family'][0],
                                               ft=plt.rcParams['pdf.fonttype'])
        fig, ax = plt.subplots(num=fig_label, figsize=(6.4, 12.4))
    
        # Cosmeticks & version info
        ax.set_xlabel("mpl " + mpl.__version__, fontsize=10)
        ax.xaxis.set_major_locator(plt.NullLocator())
        ax.yaxis.set_major_locator(plt.NullLocator())
        ax.set_ylim(-10, 600)
    
        # Plot text with bigger and bigger size
        for i, fs in enumerate(range(4, 50, 2)):
            ax.text(0.1, i*30, "{fs} pt font size".format(fs=fs), fontsize=fs)
    
        fig.savefig(fig.get_label() + ".pdf")
        plt.close(fig)
    
    
    if __name__ == "__main__":
    
        for fam, ft in [('sans', 3), ('sans', 42), ('serif', 3), ('serif', 42)]:
            plot_font_grade(fam, ft)

    results in :
    type 3 fonts (OK)
    sans_T3_grade.pdf
    serif_T3_grade.pdf
    vs type 42 fonts (does not seem OK : there are huge spaces between each character)
    sans_T42_grade.pdf
    serif_T42_grade.pdf
    whatever the font size is…

  6. QuLogic commented on Jan 27, 2017

    Member

    Bisect:

    cdea77c009c0c85640334825fdedb22bb4543374 is the first bad commit
    commit cdea77c009c0c85640334825fdedb22bb4543374
    Author: Thomas A Caswell <tcaswell@gmail.com>
    Date:   Wed Oct 28 20:38:47 2015 -0400
    
        Merge pull request #5295 from mdboom/too-many-open-files
        
        MNT: Reduce number of font file handles opened
    
    :100644 100644 6ea8d7a5d515fd568171cd3678ce7c8c5a73bde1 96dbae42b71737e0fd7b113086b408caa7834cbd M	INSTALL
    :040000 040000 d6e17bd787602c5b461e97ec363e15144e65d73a 3d14da43cdd5bbd8c1998c923d2a0065af9d757e M	lib
    :100644 100644 e294363bce578be093db779a80782c4cd905afb2 e2a6393bc4062d0408dc82afa0f2d59a6341f87a M	setup.py
    :100755 100755 dd872fdc7ebdcf5ff761c84e2679d7299354dfb1 4a31bd8f049b5ed9444c9505cd69a475e205388b M	setupext.py
    

    Seems innocuous from the title...

  7. QuLogic commented on Jan 27, 2017

    Member

    Editing matplotlib/font_manager.py and replacing get_font with:

    def get_font(*args, **kwargs):
        return ft2font.FT2Font(*args, **kwargs)

    fixes the problem, so indeed the cache is not quite right.

  8. jkseppan commented on Jan 27, 2017

    Member

    This fixes the test case too:

    diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py
    index a5e6253ca..c293fea7c 100644
    --- a/lib/matplotlib/backends/backend_pdf.py
    +++ b/lib/matplotlib/backends/backend_pdf.py
    @@ -41,6 +41,7 @@ from matplotlib.font_manager import findfont, is_opentype_cff_font, get_font
     from matplotlib.afm import AFM
     import matplotlib.type1font as type1font
     import matplotlib.dviread as dviread
    +from matplotlib.ft2font import FT2Font
     from matplotlib.ft2font import (FIXED_WIDTH, ITALIC, LOAD_NO_SCALE,
                                     LOAD_NO_HINTING, KERNING_UNFITTED)
     from matplotlib.mathtext import MathTextParser
    @@ -853,7 +854,7 @@ end"""
         def embedTTF(self, filename, characters):
             """Embed the TTF font from the named file into the document."""
     
    -        font = get_font(filename)
    +        font = FT2Font(filename)
             fonttype = rcParams['pdf.fonttype']
     
             def cvt(length, upe=font.units_per_EM, nearest=True):
  9. added
    Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
    on Jan 27, 2017
  10. added 2 commits that reference this issue on Jan 29, 2017
  11. NelleV commented on Jan 29, 2017

    Member

    Closed by #7961

  12. breedlun commented on Feb 5, 2017

    Contributor

    Glad to see this is fixed. I just ran into the same funny spacing, and spent 30 min tracking it back to Type 42 fonts.

  13. sergiocallegari commented on Mar 22, 2017

    I wonder if this could be considered serious enough to trigger the release of a 2.0.1 version of matplotlib as soon as possible, since this issue prevents upgrading from the 1.5 branch whenever you use matplotlib to prepare illustrations that need to obey some editorial flow (being in PDF, using certain fonts).

  14. jkseppan commented on Mar 22, 2017

    Member
  15. breedlun commented on Mar 22, 2017

    Contributor

    For what it's worth, I like to use type 42 fonts, but I can handle type 3 fonts. All the fonts I use come in a type 42 and type 3 version. Type 3 fonts are not editable if you import a pdf into Adobe Illustrator (or similar vector graphics programs), while type 42 fonts are editable. Matplotlib, however, creates a separate text box for every individual letter when type 42 fonts are employed. This makes it a pain to edit any word longer than one letter, so type 3 fonts are not much of a downgrade. I thought I remembered a proposal to fix matplotlib's breaking up a word into multiple text boxes, but I cannot find it anywhere.

  16. WeatherGod commented on Mar 22, 2017

    Member
  17. mdboom commented on Mar 22, 2017

    Member

    The behavior is switchable. Use the pdf.fonttype rcParam.

  18. sergiocallegari commented on Mar 22, 2017

    I'm on a linux machine (Ubuntu 16.10) where matplotlib seems to invariably pick fonts (or the font version) that show the issue. As a matter of fact, matplotlib 2.0 seems to have other font nuisances too here, like picking by default a sans serif font for math expressions in $...$. It is unclear to me how to assure that matplotlib prefers a type 3 font when the type 42 is also present.

  19. breedlun commented on Mar 23, 2017

    Contributor

    @mdboom Last I checked, pdf.fonttype only allows you to switch between type 3 and type 42. With type 3, the text is just outlined, making it totally un-editable. With type 42 you get text that is editable, but words are broken into individual characters. Having a separate text box for each character is only slightly better than un-editable text. If you are not using a fixed width font, you can't even just edit one character at a time to change a word. You have to delete all but the first text box and start from there.

    @WeatherGod I had not considered the file size issue with including the entire font package with the pdf. I like the idea of making it a rcParam, though.

  20. QuLogic commented on Mar 23, 2017

    Member

    The release is very soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.backend: pdftopic: text

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL