Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/cardinal_pythonlib/plot.py : 31%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python
2# cardinal_pythonlib/plot.py
4"""
5===============================================================================
7 Original code copyright (C) 2009-2021 Rudolf Cardinal (rudolf@pobox.com).
9 This file is part of cardinal_pythonlib.
11 Licensed under the Apache License, Version 2.0 (the "License");
12 you may not use this file except in compliance with the License.
13 You may obtain a copy of the License at
15 https://www.apache.org/licenses/LICENSE-2.0
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
23===============================================================================
25**Support for plotting via matplotlib.pyplot.**
26"""
28import io
29# noinspection PyUnresolvedReferences
30from types import ModuleType
31from typing import TYPE_CHECKING, Union
33from cardinal_pythonlib import rnc_web
35if TYPE_CHECKING:
36 try:
37 # noinspection PyPackageRequirements
38 from matplotlib.figure import Figure
39 except ImportError:
40 Figure = None
43# =============================================================================
44# Image embedding in PDFs
45# =============================================================================
46# xhtml2pdf (2013-04-11) supports PNG, but not SVG.
47# You can convert SVG to PNG for embedding:
48# https://stackoverflow.com/questions/787287
49# You could make a PDF and append it, though that would (without further
50# effort) lack the patient headers.
52def png_img_html_from_pyplot_figure(fig: "Figure",
53 dpi: int = 100,
54 extra_html_class: str = None) -> str:
55 """
56 Converts a ``pyplot`` figure to an HTML IMG tag with encapsulated PNG.
57 """
58 if fig is None:
59 return ""
60 # Make a file-like object
61 memfile = io.BytesIO()
62 # In general, can do
63 # fig.savefig(filename/file-like-object/backend, format=...)
64 # or
65 # backend.savefig(fig):
66 # see e.g. http://matplotlib.org/api/backend_pdf_api.html
67 # noinspection PyUnresolvedReferences
68 fig.savefig(memfile, format="png", dpi=dpi)
69 memfile.seek(0)
70 pngblob = memoryview(memfile.read())
71 return rnc_web.get_png_img_html(pngblob, extra_html_class)
74def svg_html_from_pyplot_figure(fig: "Figure") -> str:
75 """
76 Converts a ``pyplot`` figure to an SVG tag.
77 """
78 if fig is None:
79 return ""
80 memfile = io.BytesIO() # StringIO doesn't like mixing str/unicode
81 # noinspection PyUnresolvedReferences
82 fig.savefig(memfile, format="svg")
83 return memfile.getvalue().decode("utf-8") # returns a text/Unicode type
84 # SVG works directly in HTML; it returns <svg ...></svg>
87# =============================================================================
88# Plotting
89# =============================================================================
91def set_matplotlib_fontsize(matplotlib: ModuleType,
92 fontsize: Union[int, float] = 12) -> None:
93 """
94 Sets the current font size within the ``matplotlib`` library.
96 **WARNING:** not an appropriate method for multithreaded environments, as
97 it writes (indirectly) to ``matplotlib`` global objects. See CamCOPS for
98 alternative methods.
99 """
100 font = {
101 # https://stackoverflow.com/questions/3899980
102 # http://matplotlib.org/users/customizing.html
103 'family': 'sans-serif',
104 # ... serif, sans-serif, cursive, fantasy, monospace
105 'style': 'normal', # normal (roman), italic, oblique
106 'variant': 'normal', # normal, small-caps
107 'weight': 'normal',
108 # ... normal [=400], bold [=700], bolder [relative to current],
109 # lighter [relative], 100, 200, 300, ..., 900
110 'size': fontsize # in pt (default 12)
111 }
112 # noinspection PyUnresolvedReferences
113 matplotlib.rc('font', **font)
114 legend = {
115 # https://stackoverflow.com/questions/7125009
116 'fontsize': fontsize
117 }
118 # noinspection PyUnresolvedReferences
119 matplotlib.rc('legend', **legend)