3535import numpy as np
3636import openscm_units
3737import pandas as pd
38+ import pandas_indexing as pix
3839import pint
40+ import seaborn as sns
3941
4042import continuous_timeseries as ct
4143import continuous_timeseries .pandas_accessors
@@ -115,19 +117,21 @@ def create_df(
115117 (
116118 (s , v , r , units )
117119 for s , v , r in itertools .product (
118- [f"variable_{ i } " for i in range (n_variables )],
119120 [f"scenario_{ i } " for i in range (n_scenarios )],
121+ [f"variable_{ i } " for i in range (n_variables )],
120122 [i for i in range (n_runs )],
121123 )
122124 ),
123- columns = ["scenario" , "variable" , "region" , "units" ],
124- # This makes updates later way way faster
125+ columns = ["scenario" , "variable" , "run" , "units" ],
126+ # This makes updates and general handling later way way faster.
127+ # TODO: make this tip clearer.
125128 dtype = "category" ,
126129 )
127130 )
128131
132+ n_ts = n_scenarios * n_variables * n_runs
129133 df = pd .DataFrame (
130- np .random . random (( n_variables * n_runs * n_scenarios , timepoints .size )),
134+ 50.0 * np .linspace ( 0.3 , 1 , n_ts )[:, np . newaxis ] * np . linspace ( 0 , 1 , timepoints . size )[ np . newaxis , :] + np . random . random (( n_ts , timepoints .size )),
131135 columns = timepoints ,
132136 index = idx ,
133137 )
@@ -150,9 +154,9 @@ def create_df(
150154
151155# %%
152156small_df = create_df (
153- n_scenarios = 25 ,
154- n_variables = 10 ,
155- n_runs = 30 ,
157+ n_scenarios = 3 ,
158+ n_variables = 2 ,
159+ n_runs = 5 ,
156160 timepoints = np .arange (250 ) + 1850.0 ,
157161)
158162small_df
@@ -161,21 +165,36 @@ def create_df(
161165# Then we convert it time series.
162166
163167# %%
164- small_df .ct .to_timeseries (
168+ small_ts = small_df .ct .to_timeseries (
165169 time_units = "yr" ,
166170 interpolation = ct .InterpolationOption .PiecewiseConstantPreviousLeftClosed ,
167171)
172+ small_ts
168173
169174# %% [markdown]
170175# Then we can use standard Continuous timeseries APIs,
171176# e.g. plotting.
172177
173178# %%
179+ small_ts .ct .plot (continuous_plot_kwargs = dict (alpha = 0.3 ))
180+ # # TODO: move this to plotting
181+ # small_ts.ct.plot(continuous_plot_kwargs=dict(alpha=0.3), progress=True)
174182
175183# %% [markdown]
176- # If we have a bigger `pd.DataFrame`, this process can be much slower.
177- # If you're not sure what's happening, you can activate the progress bar if you have
178- # [`tdqm`](https://tqdm.github.io/) installed.
184+ # When combined with [pandas-indexing](https://pandas-indexing.readthedocs.io/en/latest/index.html),
185+ # this can be quite powerful for quick plots.
186+
187+ # %%
188+ ax = small_ts .loc [pix .isin (variable = "variable_0" )].ct .plot (continuous_plot_kwargs = dict (alpha = 0.3 ))
189+ ax .legend (ncols = 3 , loc = "upper center" , bbox_to_anchor = (0.5 , - 0.15 ))
190+
191+ # %%
192+ # TODO: move this to plotting section
193+ ax = small_ts .loc [pix .isin (variable = "variable_0" , run = 0 )].ct .plot (label = "scenario" , continuous_plot_kwargs = dict (alpha = 0.9 ))
194+ ax .legend ()
195+
196+ # %% [markdown]
197+ # If we have a bigger `pd.DataFrame`, the conversion process can be much slower.
179198
180199# %%
181200bigger_df = create_df (
@@ -184,7 +203,12 @@ def create_df(
184203 n_runs = 300 ,
185204 timepoints = np .arange (351 ) + 1850.0 ,
186205)
187- bigger_df
206+ bigger_df .shape
207+
208+ # %% [markdown]
209+ # If want to see the conversion's progress,
210+ # you can activate the progress bar if you have
211+ # [`tdqm`](https://tqdm.github.io/) installed.
188212
189213# %%
190214bigger_df .ct .to_timeseries (
@@ -224,7 +248,8 @@ def create_df(
224248# If you want nested progress bars in parallel,
225249# we support that too
226250# (although we're not sure if this works on windows
227- # because of the need for forking...).
251+ # because of the need for forking, for details see
252+ # [here](https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods)).
228253
229254# %%
230255bigger_df .ct .to_timeseries (
@@ -241,11 +266,55 @@ def create_df(
241266)
242267
243268# %% [markdown]
244- # - filtering with pandas-indexing
245- # - bigger df
246- # - convert more rows (progress, parallel, parallel with progress)
269+ # On big `pd.DataFrame`'s the combination with
270+ # [pandas indexing](https://pandas-indexing.readthedocs.io/)
271+ # becomes particularly powerful.
272+
273+ # %%
274+ ax = (
275+ bigger_df
276+ .loc [pix .isin (variable = "variable_1" )]
277+ .groupby (["scenario" , "variable" , "units" ], observed = True )
278+ .median ()
279+ .loc [pix .ismatch (scenario = "scenario_1*" )]
280+ .ct .to_timeseries (
281+ time_units = "yr" ,
282+ interpolation = ct .InterpolationOption .Quadratic ,
283+ )
284+ .ct .plot ()
285+ )
286+ ax .legend ()
287+
288+ # %%
289+ # # Units don't round trip
290+ # pd.testing.assert_frame_equal(
291+ # small_df,
292+ # small_ts.ct.to_df()
293+ # )
294+ small_ts .ct .to_df ()
295+
296+ # %%
297+ small_ts .ct .to_df (increase_resolution = 3 )
298+
299+ # %%
300+ sns_df = small_ts .loc [pix .isin (scenario = [f"scenario_{ i } " for i in range (2 )])].ct .to_sns_df (increase_resolution = 100 )
301+ sns_df
302+
303+ # %%
304+ sns .lineplot (
305+ data = sns_df [sns_df ["time" ] <= 1855 ],
306+ x = "time" ,
307+ y = "value" ,
308+ hue = "scenario" ,
309+ style = "variable" ,
310+ estimator = None ,
311+ units = "run" ,
312+ )
313+
314+ # %% [markdown]
247315# - other operations, also with progress, parallel, parallel with progress
248- # - convert to seaborn df for more fine-grained plotting control
249- # - also requires adding a `increase_resolution` method to `Timeseries`
316+ # - plot with basic control over labels
317+ # - plot with grouping and plumes for ranges
250318# - convert with more fine-grained control over interpolation
319+ # (e.g. interpolation being passed as pd.Series)
251320# - unit conversion
0 commit comments