Coverage for graphica/core/color_palettes.py: 75.8%

23 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-12 16:38 +0000

1""" 

2組み込みの配色パレット(読み取り専用)と、利用者のパレットの検証。 

3利用者のパレットは QSettings の custom_color_palettes_json に保存する(gui/mixins/dataset_mixin.py)。 

4""" 

5 

6from graphica.core.named_colors import normalize_color 

7from typing import Any 

8 

9# パレット管理の先頭にある「matplotlib の既定の色」の名前。設定に保存される値でもあるので変えない 

10DEFAULT_PALETTE_NAME = "Matplotlib既定" 

11 

12# 出典: Tableau 10、ColorBrewer(Set2/Dark2/Paired、パブリックドメイン)、 

13# Okabe & Ito (2008) Color Universal Design(1型/2型色覚でも判別しやすい8色)。 

14BUILTIN_PALETTES = { 

15 'Okabe-Ito(色覚多様性対応)': [ 

16 '#000000', '#e69f00', '#56b4e9', '#009e73', 

17 '#f0e442', '#0072b2', '#d55e00', '#cc79a7', 

18 ], 

19 'Tableau 10': [ 

20 '#4e79a7', '#f28e2b', '#e15759', '#76b7b2', '#59a14f', 

21 '#edc949', '#af7aa1', '#ff9da7', '#9c755f', '#bab0ab', 

22 ], 

23 'ColorBrewer Set2': [ 

24 '#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', 

25 '#ffd92f', '#e5c494', '#b3b3b3', 

26 ], 

27 'ColorBrewer Dark2': [ 

28 '#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', 

29 '#e6ab02', '#a6761d', '#666666', 

30 ], 

31 'ColorBrewer Paired': [ 

32 '#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', 

33 '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', 

34 ], 

35} 

36 

37 

38def normalize_palettes(palettes: Any) -> dict[str, list[str]]: 

39 """利用者のパレット {名前: [色, ...]} を検証し、色を小文字の #rrggbb にしたコピーを返す。""" 

40 if not isinstance(palettes, dict): 40 ↛ 41line 40 didn't jump to line 41 because the condition on line 40 was never true

41 raise ValueError("パレットは {名前: [色, ...]} の形で渡してください。") 

42 result = {} 

43 for name, colors in palettes.items(): 

44 if not isinstance(name, str) or not name.strip(): 44 ↛ 45line 44 didn't jump to line 45 because the condition on line 44 was never true

45 raise ValueError("パレット名が空です。") 

46 if name in BUILTIN_PALETTES: 46 ↛ 47line 46 didn't jump to line 47 because the condition on line 46 was never true

47 raise ValueError(f"「{name}」は組み込みのパレットと同じ名前です。") 

48 if not isinstance(colors, (list, tuple)): 48 ↛ 49line 48 didn't jump to line 49 because the condition on line 48 was never true

49 raise ValueError(f"パレット「{name}」の色はリストで渡してください。") 

50 result[name] = [normalize_color(c) for c in colors] 

51 return result 

52 

53 

54def known_palette_names(user_palettes: dict[str, list[str]]) -> set[str]: 

55 """いま使うパレットに選べる名前(既定・組み込み・利用者のパレット)。""" 

56 return {DEFAULT_PALETTE_NAME, *BUILTIN_PALETTES, *user_palettes} 

57 

58 

59def default_color_cycle() -> list[str]: 

60 """matplotlib の既定の色の並びを #rrggbb で返す。3.11 からは RGB の組で返り、QColor などに渡せない。""" 

61 import matplotlib as mpl 

62 from matplotlib.colors import to_hex 

63 

64 return [to_hex(color) for color in mpl.rcParams['axes.prop_cycle'].by_key()['color']]