lime-stable 2.0.dev3__py3-none-any.whl → 2.0.dev6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
lime/__init__.py CHANGED
@@ -42,7 +42,7 @@ _logger.debug(f'Launching LiMe {__version__} in Python {__python_version__}')
42
42
  from lime.observations import Spectrum, Sample, Cube
43
43
  from lime.io import *
44
44
  from lime.tools import *
45
- from lime.transitions import Line, label_decomposition, bands_from_frame
45
+ from lime.transitions import Line, label_decomposition, bands_from_measurements
46
46
  from lime.archives.read_fits import OpenFits, show_instrument_cfg
47
47
  from lime.plotting.plots import theme
48
48
  from lime.workflow import line_bands
@@ -154,7 +154,7 @@ def check_fits_source(fits_source, lime_object=None, load_function=None):
154
154
  else:
155
155
 
156
156
  if load_function is None:
157
- raise LiMe_Error(f'Please introduce fits file instrument or a load function to import the fits file as a '
157
+ _logger.warning(f'Please introduce fits file instrument or a load function to import the fits file as a '
158
158
  f'LiMe observation')
159
159
 
160
160
  return fits_source, spectrum_type
lime/archives/tables.py CHANGED
@@ -122,6 +122,9 @@ def table_fluxes(lines_df, table_address, header_format_latex, table_type='pdf',
122
122
  except:
123
123
  print('\n-- PDF compilation failure')
124
124
 
125
+ elif table_type == 'tex':
126
+ pdf.pdfDoc.generate_tex(table_address.as_posix())
127
+
125
128
  return
126
129
 
127
130
 
lime/changelog.txt CHANGED
@@ -105,4 +105,9 @@ LiMe Mayor update - 2.0.0 - XX/XX/XXXX
105
105
  - The central wavelenght bands are now calculated assuming a bands_vsigma=70 and n_sigma=4
106
106
  - The function lime.Spectrum.retrieve.spectrum() returns the spectrum axes as a recarray or saves it into a text file if the user provides a file address.
107
107
  - lime.Spectrum.from_file("fname", instrument='text') can now read the file from a text file following the format from the lime.Spectrum.retrieve.spectrum() function.
108
- - Bug the .plot.spectrum(include_fittings) does not show the combined profile
108
+ - Bug the .plot.spectrum(include_fittings) does not show the combined profile
109
+ - Rename term "_conf" to "_cfg" across function names and arguments for uniformity
110
+ - Fitting functions now have the update_default=True argument. In the default behaviour the default configuration updates the default one. If set to update_default=False only the obj_cfg is used if available else the default one.
111
+ - Creating a spectrum object where all the entries are masked now produces a critical warning instead of raising an error.
112
+ - By default line_bands.
113
+ - Added bands_from_log function
lime/fitting/lines.py CHANGED
@@ -180,7 +180,6 @@ def pp_FWHM(line, idx):
180
180
 
181
181
 
182
182
  def gaussian_area(line, idx, n_steps):
183
-
184
183
  amp = np.random.normal(line.amp[idx], line.amp_err[idx], n_steps)
185
184
  sigma = np.random.normal(line.sigma[idx], line.sigma_err[idx], n_steps)
186
185
 
@@ -418,7 +417,9 @@ def sigma_corrections(line, idcs_line, wave_arr, R_arr, temperature):
418
417
  if np.isscalar(R_arr):
419
418
  line.sigma_instr = np.mean(wave_arr.compressed() / (R_arr * k_gFWHM))
420
419
  else:
421
- line.sigma_instr = np.mean(wave_arr[idcs_line].compressed() / (R_arr[idcs_line] * k_gFWHM))
420
+ mask_data = ~wave_arr.mask
421
+ line.sigma_instr = np.mean(wave_arr[mask_data] / (R_arr[idcs_line][mask_data] * k_gFWHM))
422
+ wave_arr[mask_data] / (R_arr[idcs_line][mask_data] * k_gFWHM)
422
423
  else:
423
424
  line.sigma_instr = np.nan
424
425
 
@@ -468,8 +469,6 @@ class ProfileModelCompiler:
468
469
  self.model.prefix = f'line0_'
469
470
 
470
471
  # Fix or not the continuum
471
- # m_cont_conf = _SLOPE_FIX_PAR if line._cont_from_adjacent else _SLOPE_FREE_PAR
472
- # n_cont_conf = _INTER_FIX_PAR if line._cont_from_adjacent else _INTER_FREE_PAR
473
472
  self.define_param(0, line, 'm_cont', line.m_cont, _SLOPE_FIX_PAR, user_conf)
474
473
  self.define_param(0, line, 'n_cont', line.n_cont, _INTER_FIX_PAR, user_conf)
475
474
 
@@ -614,8 +613,11 @@ class ProfileModelCompiler:
614
613
  # Check for negative -0.0 # TODO this needs a better place # FIXME -0.0 error
615
614
  if np.signbit(line.sigma_err[i]):
616
615
  line.sigma_err[i] = np.nan
617
- if self.output.errorbars:
618
- _logger.warning(f'Negative value for profile sigma at {line.label}')
616
+ _logger.warning(f'Negative scale value for amplitude at {comp_label}')
617
+
618
+ if np.signbit(line.amp_err[i]):
619
+ line.amp_err[i] = np.nan
620
+ _logger.warning(f'Negative scale value for amplitude at {comp_label}')
619
621
 
620
622
  # Compute the profile areas
621
623
  profile_flux_dist = AREA_FUNCTIONS[line._p_shape[i]](line, i, 1000)
lime/fitting/redshift.py CHANGED
@@ -283,6 +283,9 @@ class RedshiftFitting:
283
283
  else:
284
284
  pred_arr, conf_arr = self._spec.infer.pred_arr, self._spec.infer.conf_arr
285
285
 
286
+ # Resolving power # TODO this should be read at another point...
287
+ res_power = self._spec.res_power if res_power is None else res_power
288
+
286
289
  # Set the type of fitting and the components to use
287
290
  if mode == 'key':
288
291
  components = components if components is not None else ['emission', 'doublet']
@@ -52,8 +52,8 @@ class LineFinder:
52
52
 
53
53
  return
54
54
 
55
- def peaks_troughs(self, bands, sigma_threshold=3, emission_type=True, width_tol=5, band_modification=None,
56
- continuum_array=None, continuum_std=None, plot_steps=False, log_scale=False):
55
+ def peaks_troughs(self, bands, sigma_threshold=3, emission_type=True, width_tol=5,
56
+ continuum_array=None, continuum_std=None, plot_steps=False, **kwargs):
57
57
 
58
58
  """
59
59
 
@@ -82,9 +82,6 @@ class LineFinder:
82
82
  :param width_tol: Minimum number of pixels between peaks/troughs. The default value is 5.
83
83
  :type width_tol: float, optional
84
84
 
85
- :param band_modification: Method to adjust the line band with. The default value is None.
86
- :type band_modification: str, optional
87
-
88
85
  :param ml_detection: Machine learning algorithm to detect lines. The default value is None.
89
86
  :type ml_detection: str, optional
90
87
 
@@ -105,101 +102,36 @@ class LineFinder:
105
102
 
106
103
  # Match peaks with theoretical lines
107
104
  bands = check_file_dataframe(bands)
108
- matched_DF = self.label_peaks(idcs_peaks, bands, width_tol=width_tol, band_modification=band_modification,
109
- line_type=emission_type)
105
+ matched_DF = self.label_peaks(idcs_peaks, bands, width_tol=width_tol, line_type=emission_type)
110
106
 
111
107
  # Plot the results
112
108
  if plot_steps:
113
- plot_peaks_troughs(self._spec, idcs_peaks, limit_threshold, continuum_array, matched_DF, log_scale)
109
+ plot_peaks_troughs(self._spec, idcs_peaks, limit_threshold, continuum_array, matched_DF, **kwargs)
114
110
 
115
111
  return matched_DF
116
112
 
117
113
 
118
- def label_peaks(self, peak_table, mask_df, line_type='emission', width_tol=5, band_modification=None, detect_check=False):
119
-
120
- # TODO auto param should be changed to boolean
121
- # Establish the type of input values for the peak indexes, first numpy array
122
- if isinstance(peak_table, np.ndarray):
123
- idcsLinePeak = peak_table
124
-
125
- # Specutils table
126
- else:
127
- # Query the lines from the astropy finder archives #
128
- if len(peak_table) != 0:
129
- idcsLineType = peak_table['emission_type'] == line_type
130
- idcsLinePeak = np.array(peak_table[idcsLineType]['line_center_index'])
131
- else:
132
- idcsLinePeak = np.array([])
114
+ def label_peaks(self, idcs_peaks, matched_DF, line_type='emission', width_tol=5):
133
115
 
134
116
  # Security check in case no lines detected
135
- if len(idcsLinePeak) == 0:
136
- return pd.DataFrame(columns=mask_df.columns)
137
-
138
- # Exclude bands not withing the regime:
139
- w0, wf = self._spec.wave_rest.data[~self._spec.wave_rest.mask][0], self._spec.wave_rest.data[~self._spec.wave_rest.mask][-1]
140
- idcs_selection = (mask_df.w3 > w0) & (mask_df.w4 < wf)
141
-
142
- # Prepare dataframe to stored the matched lines
143
- matched_DF = mask_df.loc[idcs_selection].copy()
144
- matched_DF['signal_peak'] = np.nan
145
-
146
- # Theoretical wave values
147
- waveTheory = label_decomposition(matched_DF.index.values, params_list=['wavelength'])[0]
148
- matched_DF['wavelength'] = waveTheory
149
-
150
- # Match the lines with the theoretical emission
151
- tolerance = np.diff(self._spec.wave_rest).mean() * width_tol
152
- matched_DF['observation'] = 'not_detected'
153
- unidentifiedLine = dict.fromkeys(matched_DF.columns.values, np.nan)
154
-
155
- # Get the wavelength peaks
156
- wave_peaks = self._spec.wave_rest[idcsLinePeak]
157
-
158
- for i in np.arange(wave_peaks.size):
159
-
160
- idx_array = np.where(np.isclose(a=waveTheory.astype(np.float64), b=wave_peaks[i], atol=tolerance))
161
-
162
- if len(idx_array[0]) == 0:
163
- unknownLineLabel = 'xy_{:.0f}A'.format(np.round(wave_peaks[i]))
164
-
165
- # Scheme to avoid repeated lines
166
- if (unknownLineLabel not in matched_DF.index) and detect_check:
167
- newRow = unidentifiedLine.copy()
168
- newRow.update({'wavelength': wave_peaks[i], 'w3': wave_peaks[i] - 5, 'w4': wave_peaks[i] + 5,
169
- 'observation': 'not_identified'})
170
- matched_DF.loc[unknownLineLabel] = newRow
171
-
172
- else:
173
-
174
- row_index = matched_DF.index[matched_DF.wavelength == waveTheory[idx_array[0][0]]]
175
- matched_DF.loc[row_index, 'observation'] = 'detected'
176
- matched_DF.loc[row_index, 'signal_peak'] = idcsLinePeak[i]
177
- theoLineLabel = row_index[0]
178
-
179
- blended_check = True if '_b' in theoLineLabel else False
180
- minSeparation = 4 if blended_check else 2
117
+ if len(idcs_peaks) == 0:
118
+ return pd.DataFrame(columns=matched_DF.columns)
181
119
 
182
- # Width is only computed for blended lines
183
- if band_modification is not None:
184
- if band_modification == 'auto':
185
- if blended_check is False:
186
- emission_check = True if line_type == 'emission' else False
187
- idx_min = compute_line_width(idcsLinePeak[i], self._spec.flux, delta_i=-1, min_delta=minSeparation, emission_check=emission_check)
188
- idx_max = compute_line_width(idcsLinePeak[i], self._spec.flux, delta_i=1, min_delta=minSeparation, emission_check=emission_check)
189
- matched_DF.loc[row_index, 'w3'] = self._spec.wave_rest[idx_min]
190
- matched_DF.loc[row_index, 'w4'] = self._spec.wave_rest[idx_max]
120
+ # Add theoretical wavelength values if necessary
121
+ if 'wavelength' not in matched_DF.columns:
122
+ matched_DF['wavelength'] = label_decomposition(matched_DF.index.values, params_list=['wavelength'])[0]
191
123
 
192
- # Include_only_detected
193
- idcs_unknown = matched_DF['observation'] == 'not_detected'
194
- matched_DF.drop(index=matched_DF.loc[idcs_unknown].index.values, inplace=True)
124
+ # Get bands limits indexes
125
+ idcs_w3 = np.searchsorted(self._spec.wave_rest, matched_DF.w3)
126
+ idcs_w4 = np.searchsorted(self._spec.wave_rest, matched_DF.w4)
195
127
 
196
- # Sort by wavelength
197
- matched_DF.sort_values('wavelength', inplace=True)
198
- matched_DF.drop(columns=['wavelength', 'observation'], inplace=True)
128
+ # Get the bands matching
129
+ band_contains_peak = (idcs_peaks[None, :] > idcs_w3[:, None]) & (idcs_peaks[None, :] < idcs_w4[:, None])
130
+ idcs_matched_bands = band_contains_peak.any(axis=1)
131
+ idcs_matched_peaks = idcs_peaks[band_contains_peak.argmax(axis=1)[idcs_matched_bands]]
199
132
 
200
- # Security check all bands are within selection
201
- wave_peak_matched = self._spec.wave_rest[matched_DF.signal_peak.to_numpy().astype(int)]
202
- idcs_valid = (matched_DF.w3 < wave_peak_matched) & (matched_DF.w4 > wave_peak_matched)
203
- matched_DF = matched_DF.loc[idcs_valid]
133
+ # Crop the bands to the detection
134
+ matched_DF.loc[idcs_matched_bands, 'observation'] = 'detected'
135
+ matched_DF.loc[idcs_matched_bands, 'signal_peak'] = idcs_matched_peaks
204
136
 
205
- return matched_DF
137
+ return matched_DF.loc[idcs_matched_bands]
lime/io.py CHANGED
@@ -446,8 +446,8 @@ def save_frame(fname, dataframe, page='FRAME', parameters='all', header=None, co
446
446
  output_file.write(string_DF.encode('UTF-8'))
447
447
 
448
448
  # Pdf fluxes table
449
- elif file_type == '.pdf':
450
- table_fluxes(lines_log, log_path.parent / log_path.stem, header_format_latex=_LOG_COLUMNS_LATEX,
449
+ elif file_type == '.pdf' or file_type == '.tex':
450
+ table_fluxes(lines_log, log_path.parent / log_path.stem, table_type=file_type[1:], header_format_latex=_LOG_COLUMNS_LATEX,
451
451
  lines_notation=log.latex_label.values, **kwargs)
452
452
 
453
453
  # Log in a fits format
@@ -601,7 +601,8 @@ def check_file_dataframe(df_variable, variable_type=pd.DataFrame, ext='FRAME', s
601
601
  return output
602
602
 
603
603
 
604
- def check_fit_conf(fit_conf, default_key, group_key, group_list=None, fit_cfg_suffix='_line_fitting', line_detection=False):
604
+ def check_fit_conf(fit_conf, default_key, obj_key, update_default=True, group_list=None, fit_cfg_suffix='_line_fitting',
605
+ line_detection=False):
605
606
 
606
607
  # Check that there is an input configuration
607
608
  if fit_conf is not None:
@@ -634,33 +635,30 @@ def check_fit_conf(fit_conf, default_key, group_key, group_list=None, fit_cfg_su
634
635
 
635
636
  # Recover the configuration expected for the object
636
637
  default_cfg = input_cfg.get(f'{default_key}_line_fitting') if default_key is not None else None
637
- mask_cfg = input_cfg.get(f'{group_key}_line_fitting') if group_key is not None else None
638
+ custom_cfg = input_cfg.get(f'{obj_key}_line_fitting') if obj_key is not None else None
638
639
 
639
- # Case there are not leveled entries
640
- if (default_cfg is None) and (mask_cfg is None):
640
+ # Case there are not level entries
641
+ if (default_cfg is None) and (custom_cfg is None):
641
642
  output_cfg = input_cfg
642
643
 
643
644
  # Proceed to update the levels
644
645
  else:
645
646
 
646
647
  # Default configuration
647
- output_cfg = {} if default_cfg is None else default_cfg
648
- default_detect = output_cfg.get('line_detection')
648
+ default_cfg = {} if default_cfg is None else default_cfg
649
+ default_detect = default_cfg.get('line_detection', {})
649
650
 
650
- # Mask conf
651
- mask_conf = {} if mask_cfg is None else mask_cfg
652
- mask_detect = mask_conf.get('line_detection')
651
+ # Custom configuration
652
+ custom_cfg = {} if custom_cfg is None else custom_cfg
653
+ custom_detect = custom_cfg.get('line_detection', {})
653
654
 
654
- # Update the levels
655
- output_cfg = {**output_cfg, **mask_conf}
655
+ # Update default configuration if requested else use only custom
656
+ output_cfg = {**default_cfg, **custom_cfg} if update_default else (custom_cfg if custom_cfg else default_cfg)
656
657
 
657
- # If no line detection don't add it # TODO this is wrong lower should update upper
658
- if mask_detect is not None:
659
- output_cfg['line_detection'] = mask_detect
660
- elif default_detect is not None:
661
- output_cfg['line_detection'] = default_detect
662
- else:
663
- pass
658
+ # Update default detection if requested else use only custom
659
+ if line_detection:
660
+ output_cfg['line_detection'] = default_detect.update(custom_detect) if update_default else\
661
+ (custom_detect if custom_detect else default_detect)
664
662
 
665
663
  else:
666
664
  output_cfg = {}
lime/lime.toml CHANGED
@@ -1,3 +1,3 @@
1
1
  [metadata]
2
2
  name = 'lime-stable'
3
- version = "2.0.dev3"
3
+ version = "2.0.dev6"
lime/observations.py CHANGED
@@ -142,7 +142,7 @@ def check_inputs_arrays(wave, flux, err_flux, pixel_mask, lime_object):
142
142
  # Check not all the pixels are masked
143
143
  if mask_check:
144
144
  if np.all(output_pixel_mask):
145
- raise LiMe_Error(f'All the input observation pixels are masked. Please check that only bad pixels entries'
145
+ _logger.critical(f'All the input observation pixels are masked. Please check that only bad pixels entries'
146
146
  f' are masked (in numpy arrays flux_arr[pixel_mask] = bad_entries)')
147
147
 
148
148
  return output_pixel_mask
@@ -1347,6 +1347,8 @@ class Sample(UserDict, OpenFits):
1347
1347
  else:
1348
1348
  obs = load_function_output
1349
1349
 
1350
+
1351
+
1350
1352
  return obs
1351
1353
 
1352
1354
  def __getitem__(self, id_key):
@@ -102,14 +102,7 @@ def bokeh_bands(fig, bands, x, y, z_corr, redshift):
102
102
 
103
103
  # Loop through the detections and plot the names
104
104
  for i in np.arange(latex.size):
105
- if idcs_band_limits[0, i] != idcs_band_limits[0, i]: # Y limit for the label check if same pixel
106
- max_region = np.max(y[idcs_band_limits[0, i]:idcs_band_limits[0, i]])
107
- else:
108
- max_region = y[idcs_band_limits[0, i]]
109
-
110
- label = 'Matched line' if i == 0 else '_'
111
105
  fig.add_layout(BoxAnnotation(left=w3_obs[i]/z_corr, right=w4_obs[i]/z_corr, fill_alpha=0.3, fill_color=theme.colors['match_line']))
112
- # axis.text(wave_array[i] * (1 + redshift) / z_corr, max_region * 0.9 * z_corr, latex[i], rotation=270)
113
106
 
114
107
  return
115
108
 
@@ -193,8 +186,8 @@ class BokehFigures:
193
186
 
194
187
  return
195
188
 
196
- def bands(self, label, output_address=None, ref_bands=None, include_fits=True, rest_frame=False, log_scale=True, fig_cfg=None,
197
- ax_cfg=None, return_fig=False):
189
+ def bands(self, label, output_address=None, ref_bands=None, include_fits=True, rest_frame=False, log_scale=True,
190
+ exclude_continua=True, fig_cfg=None, ax_cfg=None, return_fig=False):
198
191
 
199
192
 
200
193
  # Unpack variables
@@ -232,16 +225,13 @@ class BokehFigures:
232
225
  # Create figure with default utils if not provided
233
226
  fig = figure(tools=PLT_CONF.get('tools', "pan,wheel_zoom,box_zoom,reset,save"), y_axis_type=scale_str)
234
227
 
235
- # # Create figure with default utils if not provided
236
- # fig = figure(tools=PLT_CONF.get('tools', "pan,wheel_zoom,box_zoom,reset,save"))
237
-
238
228
  # Spectrum data source
239
229
  source = ColumnDataSource(data={"x": wave_plot[idcs_bands[0]:idcs_bands[5]] / z_corr,
240
230
  "y": flux_plot[idcs_bands[0]:idcs_bands[5]] * z_corr})
241
231
  fig.step("x", "y", source=source, color=theme.colors['fg'], line_width=1, mode='center')
242
232
 
243
233
  # Fille the bands
244
- bands_filling_bokeh(fig, wave_plot, flux_plot, z_corr, idcs_bands, line)
234
+ bands_filling_bokeh(fig, wave_plot, flux_plot, z_corr, idcs_bands, line, exclude_continua=exclude_continua)
245
235
 
246
236
  # Plot labels
247
237
  fig.xaxis.axis_label = AXES_CONF['xlabel']
@@ -250,6 +240,9 @@ class BokehFigures:
250
240
  # Adjust the format of the plot
251
241
  update_bokeh_figure(fig, PLT_CONF)
252
242
 
243
+ # Hide the legend if there are line profiles
244
+ fig.legend.visible = legend_check
245
+
253
246
  # Save or display the plot
254
247
  if return_fig:
255
248
  return fig
@@ -258,11 +251,14 @@ class BokehFigures:
258
251
  save(fig, filename=output_address)
259
252
 
260
253
  else:
261
- # output_notebook()
262
254
  show(fig)
263
255
 
256
+ else:
257
+ _logger.info(f'The input line {label} could not be found')
258
+
264
259
  return
265
260
 
261
+
266
262
  def grid(self, output_address=None, rest_frame=True, log_scale=False, n_cols=6, n_rows=None, col_row_scale=(2, 1.5),
267
263
  include_fits=True, in_fig=None, fig_cfg=None, ax_cfg=None, maximize=False):
268
264
 
@@ -270,7 +266,7 @@ class BokehFigures:
270
266
 
271
267
  def spectrum(self, output_address=None, label=None, bands=None, rest_frame=False, log_scale=False,
272
268
  include_fits=True, include_cont=False, include_components=False, return_fig=False, fig_cfg=None, ax_cfg=None, maximize=False,
273
- detection_band=None, show_masks=True, show_categories=False):
269
+ detection_band=None, show_masks=True, show_categories=False, show_err=False):
274
270
 
275
271
 
276
272
  # Set figure format with the user inputs overwriting the default conf
@@ -298,6 +294,14 @@ class BokehFigures:
298
294
  if bands is not None:
299
295
  bokeh_bands(fig, bands, wave_plot, flux_plot, z_corr, self._spec.redshift)
300
296
 
297
+ # Show uncertainty
298
+ if show_err and (self._spec.err_flux is not None):
299
+ err_plot = self._spec.err_flux.data
300
+ fig.varea_step(x=wave_plot / z_corr,
301
+ y1=(flux_plot - err_plot) * z_corr,
302
+ y2=(flux_plot + err_plot) * z_corr,
303
+ step_mode="center", fill_alpha=0.2, color=theme.colors['err_area'])
304
+
301
305
  # Include the continuum
302
306
  if include_cont and self._spec.cont is not None:
303
307
  fig.line(wave_plot/z_corr, self._spec.cont*z_corr, legend_label="Continuum.",
@@ -402,6 +406,9 @@ class BokehFigures:
402
406
  # Adjust the format of the plot
403
407
  update_bokeh_figure(fig, PLT_CONF)
404
408
 
409
+ # Hide the legend if there are line profiles
410
+ fig.legend.visible = legend_check
411
+
405
412
  # Save or display the plot
406
413
  if return_fig:
407
414
  return fig
lime/plotting/format.py CHANGED
@@ -54,6 +54,7 @@ class Themer:
54
54
  self.conf = None # All the formating data
55
55
  self.style = None # Label of the active style
56
56
  self.active_conf = None # Dictionary with the active figure configuration and library
57
+ self.default_lib = 'matplotlib'
57
58
 
58
59
  # LiMe plots personalization
59
60
  self.colors = None # Features individual colors
@@ -67,6 +68,8 @@ class Themer:
67
68
  self.conf = conf.copy()
68
69
  self.set_style(style)
69
70
 
71
+
72
+
70
73
  return
71
74
 
72
75
 
@@ -163,7 +166,7 @@ class Themer:
163
166
  return ax_cfg
164
167
 
165
168
 
166
- def set_style(self, style=None, scale=None, colors_conf=None, library=None):
169
+ def set_style(self, style=None, scale=None, colors_conf=None, library='matplotlib'):
167
170
 
168
171
  # Set the default style
169
172
  # self.style = ['default']
@@ -173,6 +176,7 @@ class Themer:
173
176
  # self.style += [style] if isinstance(style, str) else style
174
177
  self.style = 'default' if style is None else style
175
178
  self.scale = ['default'] if style is None else [scale]
179
+ self.default_lib = library
176
180
 
177
181
  # Set the library defaults
178
182
  self.active_conf = {'matplotlib': self.conf['matplotlib']['default'].copy(),