@@ -104,6 +104,10 @@ def change_plot_create(
104104 it was changed. For tags that were unchanged, this will be infinity.
105105 final_observation_col: Column name for the days elapsed from when the tag was
106106 added to when this data was downloaded.
107+ title: Title of the plot.
108+ subtitle: Subtitle of the plot.
109+ x_label: Label for the x-axis.
110+ y_label: Label for the y-axis.
107111 day_range: Maximum elapsed time period to plot, in days
108112
109113 Returns:
@@ -122,9 +126,9 @@ def change_plot_create(
122126 data = reshaped ,
123127 mapping = gg .aes (x = 'year' , ymin = 'ymin' , ymax = 'ymax' )
124128 ) +
125- gg .geom_ribbon (fill = 'blue' , alpha = 0.4 ) +
126- gg .geom_line (mapping = gg .aes (y = 'ymin' ), color = 'black' , alpha = 0.5 ) +
127- gg .geom_line (mapping = gg .aes (y = 'ymax' ), color = 'black' , alpha = 0.5 ) +
129+ gg .geom_ribbon (fill = 'blue' , alpha = 0.25 ) +
130+ gg .geom_line (mapping = gg .aes (y = 'ymin' ), color = 'black' , linetype = 'dashed' ) +
131+ gg .geom_line (mapping = gg .aes (y = 'ymax' ), color = 'black' ) +
128132 gg .labs (
129133 title = title ,
130134 subtitle = subtitle ,
@@ -153,15 +157,31 @@ def change_multiplot_create(
153157 no_change_col : str = 'no_change' ,
154158 change_col : str = 'change' ,
155159 final_observation_col : str = 'final_obs' ,
160+ title : str = None ,
161+ subtitle : str = None ,
162+ x_label : str = '' ,
163+ y_label : str = '' ,
156164 day_range : int = 365 * 10 ,
157165) -> gg .ggplot :
158166 """
159167 Create a multi-panel change plot.
160168
161169 Args:
162- col: Column name for the tag to plot.
170+ observations: DataFrame with observations. Each row is an iteration of a
171+ tag, with the three columns described below.
172+ col: Column name for the OSM grouping tag to plot.
163173 top_n: Number of tags to plot, ordered by number of observations.
164- **kwargs: Keyword arguments for change_plot_create.
174+ no_change_col: Column name for the days elapsed from when the tag was added to
175+ when it was last confirmed (observed unchanged).
176+ change_col: Column name for the days elapsed from when the tag was added to when
177+ it was changed. For tags that were unchanged, this will be infinity.
178+ final_observation_col: Column name for the days elapsed from when the tag was
179+ added to when this data was downloaded.
180+ title: Title of the plot.
181+ subtitle: Subtitle of the plot.
182+ x_label: Label for the x-axis.
183+ y_label: Label for the y-axis.
184+ day_range: Maximum elapsed time period to plot, in days
165185
166186 Returns:
167187 ggplot object
@@ -171,24 +191,49 @@ def change_multiplot_create(
171191 obs_sub = observations .dropna (subset = [col ])
172192 top_tags = obs_sub [col ].value_counts ().head (top_n )
173193 # Create a list of ggplot objects
174- fig_list = []
194+ reshaped_list = []
175195 for tag , _ in top_tags .items ():
176196 obs_sub_tag = obs_sub .query (f"{ col } == @tag" )
177- fig = change_plot_create (
178- observations = obs_sub_tag ,
179- title = tag .title (),
180- subtitle = f"N = { obs_sub_tag .shape [0 ]} " ,
181- no_change_col = no_change_col ,
182- change_col = change_col ,
183- final_observation_col = final_observation_col ,
184- day_range = day_range ,
197+ reshaped_sub = (
198+ change_plot_reshape_data (
199+ observations = obs_sub_tag ,
200+ no_change_col = no_change_col ,
201+ change_col = change_col ,
202+ final_observation_col = final_observation_col ,
203+ day_range = day_range
204+ )
205+ .assign (
206+ group = tag .replace ("_" , " " ).title () + f" (N = { obs_sub_tag .shape [0 ]} )"
207+ )
185208 )
186- fig_list .append (fig )
187- # Compose the individual plots into a roughly square grid
188- n_rows = np .ceil (np .sqrt (len (fig_list )))
189- composed_rows = [
190- reduce (lambda gg1 , gg2 : gg1 | gg2 , row )
191- for row in np .array_split (fig_list , n_rows )
192- ]
193- composed_fig = reduce (lambda row1 , row2 : row1 / row2 , composed_rows )
194- return composed_fig
209+ reshaped_list .append (reshaped_sub )
210+ # Create a grouped change plot
211+ reshaped_full = pd .concat (reshaped_list )
212+ year_range = day_range / 365
213+ fig = (
214+ gg .ggplot (
215+ data = reshaped_full ,
216+ mapping = gg .aes (x = 'year' , color = 'group' )
217+ ) +
218+ gg .geom_line (mapping = gg .aes (y = 'ymin' ), linetype = 'dashed' ) +
219+ gg .geom_line (mapping = gg .aes (y = 'ymax' )) +
220+ gg .labs (
221+ title = title ,
222+ subtitle = subtitle ,
223+ x = x_label ,
224+ y = y_label ,
225+ color = col .replace ("_" , " " ).title ()
226+ ) +
227+ gg .scale_y_continuous (
228+ limits = (0 , 1.01 ),
229+ breaks = np .arange (0 , 1.01 , 0.25 ),
230+ labels = [f"{ x * 100 :.0f} %" for x in np .arange (0 , 1.01 , 0.25 )],
231+ ) +
232+ gg .scale_x_continuous (
233+ limits = (0 , year_range + 0.01 ),
234+ breaks = np .arange (year_range + 1 ),
235+ labels = [f"{ x :.0f} " for x in np .arange (year_range + 1 )],
236+ ) +
237+ gg .theme_bw ()
238+ )
239+ return fig
0 commit comments