Coverage for pySDC/helpers/plot_helper.py: 94%

33 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-25 20:28 +0000

1import matplotlib as mpl 

2import matplotlib.pyplot as plt 

3import shutil 

4 

5default_mpl_params = mpl.rcParams.copy() 

6 

7 

8def figsize(textwidth, scale, ratio): 

9 """ 

10 Get figsize. 

11 

12 Args: 

13 textwidth (str): Textwdith in your LaTeX file in points 

14 scale (float): The width of the figure relative to the textwidth 

15 ratio (float): The height of the figure relative to its width 

16 

17 Returns: 

18 list: Width and height of the figure to be passed to matplotlib 

19 """ 

20 fig_width_pt = textwidth # Get this from LaTeX using \the\textwidth 

21 inches_per_pt = 1.0 / 72.27 # Convert pt to inch 

22 fig_width = fig_width_pt * inches_per_pt * scale # width in inches 

23 fig_height = fig_width * ratio # height in inches 

24 fig_size = [fig_width, fig_height] 

25 return fig_size 

26 

27 

28def figsize_by_journal(journal, scale, ratio): # pragma: no cover 

29 """ 

30 Get figsize for specific journal. If you supply a text height, we will rescale the figure to fit on the page instead 

31 of the parameters supplied. 

32 

33 Args: 

34 journal (str): Name of journal 

35 scale (float): The width of the figure relative to the textwidth 

36 ratio (float): The height of the figure relative to its width 

37 

38 Returns: 

39 list: Width and height of the figure to be passed to matplotlib 

40 """ 

41 # store text width in points here, get this from LaTeX using \the\textwidth 

42 textwidths = { 

43 'JSC_beamer': 426.79135, 

44 'Springer_Numerical_Algorithms': 338.58778, 

45 'Springer_proceedings': 347.12354, 

46 'JSC_thesis': 434.26027, 

47 'TUHH_thesis': 426.79135, 

48 'Nature_CS': 372.0, 

49 'CPC': 468.3324, 

50 } 

51 # store text height in points here, get this from LaTeX using \the\textheight 

52 textheights = { 

53 'JSC_beamer': 214.43411, 

54 'JSC_thesis': 635.5, 

55 'TUHH_thesis': 631.65118, 

56 'Springer_proceedings': 549.13828, 

57 'Nature_CS': 552.69478, 

58 'CPC': 637.31475, 

59 } 

60 assert ( 

61 journal in textwidths.keys() 

62 ), f"Textwidth only available for {list(textwidths.keys())}. Please implement one for \"{journal}\"! Get the textwidth using \"\\the\\textwidth\" in your tex file." 

63 

64 # see if the figure fits on the page or if we need to apply the scaling to the height instead 

65 if scale * ratio * textwidths[journal] > textheights.get(journal, 1e9): 

66 if textheights[journal] / scale / ratio > textwidths[journal]: 

67 raise ValueError( 

68 f"We cannot fit figure with scale {scale:.2f} and ratio {ratio:.2f} on the page for journal {journal}!" 

69 ) 

70 return figsize(textheights[journal] / (scale * ratio), 1, ratio) 

71 

72 return figsize(textwidths[journal], scale, ratio) 

73 

74 

75def setup_mpl(font_size=8, reset=False): 

76 if reset: 

77 mpl.rcParams.update(default_mpl_params) 

78 

79 # Set up plotting parameters 

80 style_options = { # setup matplotlib to use latex for output 

81 "font.family": "serif", 

82 "font.serif": [], # blank entries should cause plots to inherit fonts from the document 

83 "font.sans-serif": [], 

84 "font.monospace": [], 

85 # "axes.labelsize": 8, # LaTeX default is 10pt font. 

86 "axes.linewidth": 0.5, 

87 "font.size": font_size, 

88 # "legend.fontsize": 6, # Make the legend/label fonts a little smaller 

89 "legend.numpoints": 1, 

90 # "xtick.labelsize": 6, 

91 "xtick.major.width": 0.5, # major tick width in points 

92 "xtick.minor.width": 0.25, 

93 # "ytick.labelsize": 6, 

94 "ytick.major.width": 0.5, # major tick width in points 

95 "ytick.minor.width": 0.25, 

96 "lines.markersize": 4, 

97 "lines.markeredgewidth": 0.5, 

98 "grid.linewidth": 0.5, 

99 "grid.linestyle": '-', 

100 "grid.alpha": 0.25, 

101 "figure.subplot.hspace": 0.0, 

102 "savefig.pad_inches": 0.01, 

103 } 

104 

105 mpl.rcParams.update(style_options) 

106 

107 if shutil.which('latex'): 

108 latex_support = { 

109 "pgf.texsystem": "pdflatex", # change this if using xetex or lautex 

110 "text.usetex": True, # use LaTeX to write all text 

111 "pgf.preamble": r"\usepackage[utf8x]{inputenc}" 

112 r"\usepackage[T1]{fontenc}" 

113 r"\usepackage{underscore}" 

114 r"\usepackage{amsmath,amssymb,marvosym}", 

115 } 

116 else: 

117 latex_support = { 

118 "text.usetex": False, # use LaTeX to write all text 

119 } 

120 

121 mpl.rcParams.update(latex_support) 

122 plt.close('all') 

123 

124 

125def newfig(textwidth, scale, ratio=0.6180339887): 

126 plt.clf() 

127 fig, ax = plt.subplots(figsize=figsize(textwidth, scale, ratio)) 

128 return fig, ax 

129 

130 

131def savefig(filename, save_pdf=True, save_pgf=True, save_png=True): 

132 if save_pgf and shutil.which('latex'): 

133 plt.savefig('{}.pgf'.format(filename), bbox_inches='tight') 

134 if save_pdf: 

135 plt.savefig('{}.pdf'.format(filename), bbox_inches='tight') 

136 if save_png: 

137 plt.savefig('{}.png'.format(filename), bbox_inches='tight') 

138 plt.close()