matplotlib.font_manager debug messages in log file
Asked Answered
G

3

8

I want to log the progress of my optimization in a log file, but my log file gets filled with stuff from the matplotlib font manager, e.g.:

DEBUG:matplotlib.font_manager:findfont: Matching :family=sans-serif:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0.)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'STIXSizeThreeSym' (STIXSizThreeSymBol.ttf) normal normal bold normal>) = 10.335)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'cmmi10' (cmmi10.ttf) normal normal 400 normal>) = 10.05)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'STIXSizeTwoSym' (STIXSizTwoSymReg.ttf) normal normal regular normal>) = 10.05)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'cmsy10' (cmsy10.ttf) normal normal 400 normal>) = 10.05)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'DejaVu Sans' (DejaVuSans-BoldOblique.ttf) oblique normal bold normal>) = 1.335)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'DejaVu Sans Mono' (DejaVuSansMono-BoldOblique.ttf) oblique normal bold normal>) = 11.335)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'STIXSizeOneSym' (STIXSizOneSymReg.ttf) normal normal regular normal>) = 10.05)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'DejaVu Sans Mono' (DejaVuSansMono.ttf) normal normal 400 normal>) = 10.05)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'DejaVu Sans' (DejaVuSans-Bold.ttf) normal normal bold normal>) = 0.33499999999999996)
DEBUG:matplotlib.font_manager:findfont: score(<Font 'DejaVu Sans Mono' (DejaVuSansMono-Bold.ttf) normal normal bold normal>) = 10.335)

I'm using the logger as follows:

import logging

logger=logging.getLogger(__name__)

logging.basicConfig(filename='logfile.log',level=logging.DEBUG,
                    format='%(levelname)s:%(name)s:%(message)s)')

def objective(x):

    obj=model(x)
    logger.debug('objective = {}'.format(obj))

    return obj

How can I keep matplotlib from crapping all over my log file?

Goneness answered 10/10, 2019 at 10:14 Comment(7)
Try removing level=logging.DEBUG from the basicConfig and adding a line below that is logger.setLevel(logging.DEBUG). Does that work?Pheni
no, that did not work :(Goneness
I'm a little surprised that doesn't work for you. Are you able to make a minimal reproducible example that we can just copy and paste to see the problem?Pheni
your solution works. I thought there was a new log file at every run, but it is just appending the new logs to the old file. once I deleted the file, it was all good :)Goneness
but why? this sounds like a bug.... is it a feature?Cough
If you want to continue to use basicConfig, you can also change the logging level of matplotlib.font_manager: logging.getLogger('matplotlib.font_manager').setLevel(logging.WARNING)Mahout
... or set all of matplotlib to warning level: logging.getLogger('matplotlib').setLevel(logging.WARNING)Bendick
G
9

The solution was provided by tomjn:

level=logging.DEBUG from the basicConfig was removed and in the line below logger.setLevel(logging.DEBUG) was added. So that makes

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
Goneness answered 11/10, 2019 at 13:46 Comment(2)
How to specifically remove the logs of font_manager ?Mcgraw
Try this: logging.getLogger('matplotlib.font_manager').disabled = TrueFallon
O
2

With full credit to @SimoX:

Add this line to suppress all that garbage from matplotlib.font_manager:

logging.getLogger('matplotlib.font_manager').disabled = True
Outpouring answered 2/3, 2023 at 16:15 Comment(0)
H
0

The accepted answer didn't work for me, avoidance is another strategy.

I use the logging module's dictConfig to create and configure module level loggers, then call them at the top of each module. This allows me to set the level on a module basis, thus for my use case using a named logger rather than the root logger was no loss.

In config['loggers'][""] the root logger is set to INFO so none of the DEBUG:matplotlib.font_manager:findfont appears in my log records yet I still get what I need out of logging.

I recognize the recommendation in the docs is to use logging.getLogger(__name__) and this doesn't conform to that.

import logging
from logging.config import dictConfig
    
config = {'version': 1,
                  'disable_existing_loggers': False,
                  'formatters': {'standard': {'format': '''%(levelname)-10s: %(name)-10s: %(funcName)20s() line %(lineno)d: %(message)s'''}},
                  'handlers': {'default': {'level': 'DEBUG',
                                           'formatter': 'standard',
                                           'class': 'logging.StreamHandler',
                                           'stream': 'ext://sys.stdout'},
                               'file': {'level': 'WARNING',
                                        'formatter': 'standard',
                                        'class': 'logging.FileHandler',
                                        'filename': 'logs/dict_simple.log'}},
                  'loggers': {"": {'level': "INFO",
                                   'handlers': ['default', 'file'],
                                   'propagate': True},
                              "my_logger": {'level': "DEBUG",
                                               'handlers': ['default', 'file'],
                                               'propagate': False}

                              }} 
dictConfig(config) 
log = logging.getLogger('my_logger')
Heavensent answered 11/5 at 12:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.