|
8 | 8 | # https://github.com/mwaskom/seaborn/blob/master/seaborn/rcmod.py |
9 | 9 | import re |
10 | 10 | import os |
11 | | -import yaml |
12 | 11 | import numpy as np |
13 | 12 | import cycler |
14 | 13 | import matplotlib.colors as mcolors |
@@ -667,6 +666,69 @@ def _sanitize_key(key): |
667 | 666 | return key.lower() |
668 | 667 |
|
669 | 668 |
|
| 669 | +def _update_from_file(file): |
| 670 | + """ |
| 671 | + Apply updates from a file. This is largely copied from matplotlib. |
| 672 | +
|
| 673 | + Parameters |
| 674 | + ---------- |
| 675 | + file : str |
| 676 | + The path. |
| 677 | + """ |
| 678 | + cnt = 0 |
| 679 | + file = os.path.expanduser(file) |
| 680 | + added = set() |
| 681 | + with open(file, 'r') as fd: |
| 682 | + for line in fd: |
| 683 | + # Read file |
| 684 | + cnt += 1 |
| 685 | + stripped = line.split('#', 1)[0].strip() |
| 686 | + if not stripped: |
| 687 | + continue |
| 688 | + pair = stripped.split(':', 1) |
| 689 | + if len(pair) != 2: |
| 690 | + _warn_proplot( |
| 691 | + f'Illegal line #{cnt} in file {file!r}:\n{line!r}"' |
| 692 | + ) |
| 693 | + continue |
| 694 | + key, value = pair |
| 695 | + key = key.strip() |
| 696 | + value = value.strip() |
| 697 | + if key in added: |
| 698 | + _warn_proplot( |
| 699 | + f'Duplicate key {key!r} on line #{cnt} in file {file!r}.' |
| 700 | + ) |
| 701 | + added.add(key) |
| 702 | + |
| 703 | + # *Very primitive* type conversion system. Just check proplot |
| 704 | + # settings (they are all simple/scalar) and leave rcParams alone. |
| 705 | + # TODO: Add built-in validation by making special RcParamsLong |
| 706 | + # and RcParamsShort classes just like matplotlib RcParams |
| 707 | + if key in rcParamsShort or key in rcParamsLong: |
| 708 | + if not value: |
| 709 | + value = None # older proplot versions supported this |
| 710 | + elif value in ('True', 'False', 'None'): |
| 711 | + value = eval(value) # rare case where eval is o.k. |
| 712 | + else: |
| 713 | + try: |
| 714 | + # int-float distinction does not matter in python3 |
| 715 | + value = float(value) |
| 716 | + except ValueError: |
| 717 | + pass |
| 718 | + |
| 719 | + # Add to dictionaries |
| 720 | + try: |
| 721 | + rc_short, rc_long, rc = _get_synced_params(key, value) |
| 722 | + except KeyError: |
| 723 | + _warn_proplot( |
| 724 | + f'Invalid key {key!r} on line #{cnt} in file {file!r}.' |
| 725 | + ) |
| 726 | + else: |
| 727 | + rcParamsShort.update(rc_short) |
| 728 | + rcParamsLong.update(rc_long) |
| 729 | + rcParams.update(rc) |
| 730 | + |
| 731 | + |
670 | 732 | class rc_configurator(object): |
671 | 733 | """ |
672 | 734 | Magical abstract class for managing matplotlib |
@@ -727,21 +789,7 @@ def __init__(self, local=True): |
727 | 789 | for i, file in enumerate(_get_config_paths()): |
728 | 790 | if not os.path.exists(file): |
729 | 791 | continue |
730 | | - with open(file) as f: |
731 | | - try: |
732 | | - data = yaml.safe_load(f) |
733 | | - except yaml.YAMLError as err: |
734 | | - print('{file!r} has invalid YAML syntax.') |
735 | | - raise err |
736 | | - for key, value in (data or {}).items(): |
737 | | - try: |
738 | | - rc_short, rc_long, rc = _get_synced_params(key, value) |
739 | | - except KeyError: |
740 | | - raise RuntimeError(f'{file!r} has invalid key {key!r}.') |
741 | | - else: |
742 | | - rcParamsShort.update(rc_short) |
743 | | - rcParamsLong.update(rc_long) |
744 | | - rcParams.update(rc) |
| 792 | + _update_from_file(file) |
745 | 793 |
|
746 | 794 | def __enter__(self): |
747 | 795 | """Apply settings from the most recent context block.""" |
|
0 commit comments