Skip to content

Commit 8acb8bb

Browse files
committed
enable automatic matplotlib fallback
1 parent 852eb5d commit 8acb8bb

File tree

5 files changed

+112
-165
lines changed

5 files changed

+112
-165
lines changed

pypop/matplotlib/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: BSD-3-Clause-Clear
3+
# Copyright (c) 2019, The Numerical Algorithms Group, Ltd. All rights reserved.
4+
5+
from .builtin import *
6+
7+
__all__ = []

pypop/cli/mpl_plotting.py renamed to pypop/matplotlib/builtin.py

Lines changed: 6 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@
44

55
import numpy
66
import pandas
7-
from sys import float_info
87

98
from matplotlib.backends.backend_agg import FigureCanvasAgg
109
from matplotlib.figure import Figure
1110
import matplotlib.cm as mcm
1211
import matplotlib.colors as mc
13-
import matplotlib as mpl
1412
import matplotlib.table as mt
1513
import matplotlib.ticker as mtick
1614

17-
from ..metrics.metricset import MetricSet
18-
from ..utils.plot import approx_string_em_width, get_pop_logo_data
15+
from pypop.metrics.metricset import MetricSet
16+
from pypop.utils.plot import approx_string_em_width, get_pop_logo_data
17+
18+
from .mplplotbase import MPLPlotBase
19+
20+
__all__ = ["MPLMetricTable", "MPLScalingPlot"]
1921

2022

2123
def build_discrete_cmap(factors):
@@ -31,28 +33,6 @@ def build_discrete_cmap(factors):
3133
return {k: cmap(i / (len(factors) - 1)) for i, k in enumerate(factors)}
3234

3335

34-
class MPLPlotBase(object):
35-
def __init__(self):
36-
self._figure = None
37-
38-
def _build_plot(self):
39-
raise NotImplementedError("MPLPlotBase should not be used directly!")
40-
41-
@property
42-
def figure(self):
43-
if not self._figure:
44-
self._build_plot()
45-
return self._figure
46-
47-
def _repr_png_(self):
48-
imgbuffer = BytesIO()
49-
self.figure.savefig(imgbuffer, format="png")
50-
return imgbuffer.getvalue()
51-
52-
def save_png(self, filename):
53-
self.figure.savefig(filename, format="png")
54-
55-
5636
class MPLScalingPlot(MPLPlotBase):
5737
def __init__(
5838
self,
@@ -174,8 +154,6 @@ def _build_plot(self):
174154
lw=0,
175155
)
176156

177-
xmin = float_info.max
178-
xmax = 0
179157
for group, groupdata in plot_data.groupby("Plotgroups", sort=False):
180158
groupdata = groupdata.sort_values(self._xaxis_key)
181159
self._figax.plot(
@@ -346,15 +324,12 @@ def _build_plot(self):
346324
self._logo_height / plot_height, # Logo height
347325
]
348326

349-
print("Logo Ax: {:.2f}, {:.2f}, {:.2f}, {:.2f}".format(*logo_ax_layout))
350-
351327
self._logo_ax = self._figure.add_axes(logo_ax_layout, frame_on=False)
352328
self._logo_ax.xaxis.set_visible(False)
353329
self._logo_ax.yaxis.set_visible(False)
354330

355331
self._logo_ax.imshow(pop_data, origin="lower")
356332

357-
print("Tabl Ax: {:.2f}, {:.2f}, {:.2f}, {:.2f}".format(*table_ax_layout))
358333
self._table_ax = self._figure.add_axes(table_ax_layout, frame_on=False)
359334

360335
self._table_ax.xaxis.set_visible(False)
@@ -501,120 +476,3 @@ def efficiency_cmap(self, value):
501476
return self._eff_cmap(-1)
502477

503478
return self._eff_cmap(value)
504-
505-
506-
def _plot_table(
507-
self, columns_key, title, columns_label, good_thres, bad_thres, skipfirst, bwfirst,
508-
):
509-
510-
if not columns_key:
511-
columns_values = self.metric_data.index
512-
if columns_label is None:
513-
columns_label = "Index"
514-
else:
515-
columns_values = self.metric_data[columns_key]
516-
if not columns_label:
517-
columns_label = columns_key
518-
519-
label_cell_width = 0.60
520-
body_cell_width = (1 - label_cell_width) / (len(columns_values) - skipfirst)
521-
body_cell_height = 0.1
522-
level_pad = 0.075
523-
524-
pop_red = (0.690, 0.074, 0.074)
525-
pop_fade = (0.992, 0.910, 0.910)
526-
pop_green = (0.074, 0.690, 0.074)
527-
528-
ineff_points = [
529-
(0.0, pop_green),
530-
(1 - good_thres, pop_fade),
531-
(1 - good_thres + 1e-20, pop_fade),
532-
(1 - bad_thres, pop_red),
533-
(1.0, pop_red),
534-
]
535-
536-
eff_points = [
537-
(0.0, pop_red),
538-
(bad_thres, pop_red),
539-
(good_thres - 1e-20, pop_fade),
540-
(good_thres, pop_fade),
541-
(1.0, pop_green),
542-
]
543-
544-
ineff_cmap = mc.LinearSegmentedColormap.from_list(
545-
"POP_Metrics", colors=ineff_points, N=256, gamma=1
546-
)
547-
548-
eff_cmap = mc.LinearSegmentedColormap.from_list(
549-
"POP_Metrics", colors=eff_points, N=256, gamma=1
550-
)
551-
552-
label_cell_kwargs = {
553-
"loc": "left",
554-
"width": label_cell_width,
555-
"height": body_cell_height,
556-
}
557-
body_cell_kwargs = {
558-
"loc": "center",
559-
"width": body_cell_width,
560-
"height": body_cell_height,
561-
}
562-
563-
fig = plt.figure(figsize=figparams["single.figsize"])
564-
ax = [fig.add_axes(fp) for fp in figparams["single.axlayout"]]
565-
ax[0].set_axis_off()
566-
567-
# Create empty table using full bounding box of axes
568-
metric_table = mt.Table(ax=ax[0], bbox=(0, 0, 1, 1))
569-
metric_table.auto_set_font_size(True)
570-
# metric_table.set_fontsize(8)
571-
572-
metric_table.add_cell(
573-
0,
574-
0,
575-
width=label_cell_width,
576-
height=body_cell_height,
577-
text=columns_label,
578-
loc="center",
579-
)
580-
581-
for col_num, col_data in enumerate(columns_values, start=1):
582-
if col_num <= skipfirst:
583-
continue
584-
metric_table.add_cell(
585-
0, col_num - skipfirst, text="{}".format(col_data), **body_cell_kwargs
586-
)
587-
588-
for row_num, metric in enumerate(self.metrics, start=1):
589-
cmap = ineff_cmap if metric.is_inefficiency else eff_cmap
590-
c = metric_table.add_cell(
591-
row_num, 0, text=metric.displayname, **label_cell_kwargs
592-
)
593-
c.PAD = 0.05
594-
c.PAD += 0 if metric.level <= 1 else level_pad * (metric.level - 1)
595-
596-
for col_num, col_data in enumerate(self.metric_data[metric.key], start=1):
597-
if col_num <= skipfirst:
598-
continue
599-
if col_num <= bwfirst:
600-
metric_table.add_cell(
601-
row_num,
602-
col_num,
603-
text="{:1.02f}".format(col_data),
604-
**body_cell_kwargs
605-
)
606-
else:
607-
metric_table.add_cell(
608-
row_num,
609-
col_num - skipfirst,
610-
text="{:1.02f}".format(col_data),
611-
facecolor=cmap(col_data),
612-
**body_cell_kwargs
613-
)
614-
615-
ax[0].add_table(metric_table)
616-
617-
if title:
618-
ax[0].set_title(title)
619-
620-
return fig

pypop/matplotlib/mplplotbase.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: BSD-3-Clause-Clear
3+
# Copyright (c) 2019, The Numerical Algorithms Group, Ltd. All rights reserved.
4+
5+
from io import BytesIO
6+
7+
8+
class MPLPlotBase(object):
9+
def __init__(self):
10+
self._figure = None
11+
12+
def _build_plot(self):
13+
raise NotImplementedError("MPLPlotBase should not be used directly!")
14+
15+
@property
16+
def figure(self):
17+
if not self._figure:
18+
self._build_plot()
19+
return self._figure
20+
21+
def _repr_png_(self):
22+
imgbuffer = BytesIO()
23+
self.figure.savefig(imgbuffer, format="png")
24+
return imgbuffer.getvalue()
25+
26+
def save_png(self, filename):
27+
self.figure.savefig(filename, format="png")

0 commit comments

Comments
 (0)