├── .github ├── FUNDING.yml └── workflows │ └── python-package.yml ├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── bar_chart_race ├── __init__.py ├── _bar_chart_race.py ├── _bar_chart_race_plotly.py ├── _codes │ ├── code_value.csv │ ├── country.csv │ └── nfl.csv ├── _colormaps.py ├── _common_chart.py ├── _func_animation.py ├── _line_chart_race.py ├── _pandas_accessor.py └── _utils.py ├── data ├── baseball.csv ├── covid19.csv ├── covid19_tutorial.csv └── urban_pop.csv ├── docs ├── css │ └── style.css ├── data_preparation.md ├── images │ ├── bcr_notebook.png │ ├── covid19_horiz.gif │ ├── prepare_long.png │ └── wide_data.png ├── index.md ├── installation.md ├── tutorial.md ├── upcoming.md └── whats_new.md ├── mkdocs.yml ├── setup.py └── tests ├── __init__.py ├── data └── lcr_data.csv ├── test_bar_charts.py ├── test_line_chart.py ├── test_plotly.py ├── test_prepare.py └── videos └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ['https://www.dunderdata.com'] 2 | -------------------------------------------------------------------------------- /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | matrix: 18 | os: [ubuntu-latest, macos-latest, windows-latest] 19 | python-version: [3.6, 3.7, 3.8] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Set up Python ${{ matrix.python-version }} 24 | uses: actions/setup-python@v2 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | - name: Download ffmpeg linux 28 | if: ${{ matrix.os == 'ubuntu-latest' }} 29 | run: | 30 | sudo apt-get update 31 | sudo apt-get install ffmpeg 32 | sudo apt install ffmpeg 33 | - name: Download ffmpeg mac 34 | if: ${{ matrix.os == 'macos-latest' }} 35 | run: brew install ffmpeg 36 | - name: Download ffmpeg windows 37 | if: ${{ matrix.os == 'windows-latest' }} 38 | run: choco install ffmpeg --no-progress 39 | - name: Install dependencies 40 | run: | 41 | python -m pip install --upgrade pip 42 | pip install pytest matplotlib==3.2 pandas plotly 43 | - name: Test with pytest 44 | run: | 45 | pytest 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | notebooks/ 3 | .DS_Store 4 | *egg-info/ 5 | build/ 6 | dist/ 7 | site/ 8 | *.mp4 9 | docs/ 10 | data/ 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 dexplo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE bar_chart_race/_codes/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bar Chart Race 2 | 3 | [![](https://img.shields.io/pypi/v/bar_chart_race)](https://pypi.org/project/bar_chart_race) 4 | [![PyPI - License](https://img.shields.io/pypi/l/bar_chart_race)](LICENSE) 5 | 6 | Make animated bar and line chart races in Python with matplotlib or plotly. 7 | 8 | ![img](https://github.com/dexplo/bar_chart_race/raw/gh-pages/images/covid19_horiz.gif) 9 | 10 | ## Official Documentation 11 | 12 | Visit the [bar_chart_race official documentation](https://www.dexplo.org/bar_chart_race) for detailed usage instructions. 13 | 14 | ## Installation 15 | 16 | Install with either: 17 | 18 | * `pip install bar_chart_race` 19 | * `conda install -c conda-forge bar_chart_race` 20 | 21 | ## Quickstart 22 | 23 | Must begin with a pandas DataFrame containing 'wide' data where: 24 | 25 | * Every row represents a single period of time 26 | * Each column holds the value for a particular category 27 | * The index contains the time component (optional) 28 | 29 | The data below is an example of properly formatted data. It shows total deaths from COVID-19 for several countries by date. 30 | 31 | ![img](https://github.com/dexplo/bar_chart_race/raw/gh-pages/images/wide_data.png) 32 | 33 | ### Create bar and line chart races 34 | 35 | There are three core functions available to construct the animations. 36 | 37 | * `bar_chart_race` 38 | * `bar_chart_race_plotly` 39 | * `line_chart_race` 40 | 41 | The above animation was created with the help of matplotlib using the following call to `bar_chart_race`. 42 | 43 | ```python 44 | import bar_chart_race as bcr 45 | df = bcr.load_dataset('covid19_tutorial') 46 | bcr.bar_chart_race( 47 | df=df, 48 | filename='../docs/images/covid19_horiz.gif', 49 | orientation='h', 50 | sort='desc', 51 | n_bars=8, 52 | fixed_order=False, 53 | fixed_max=True, 54 | steps_per_period=20, 55 | period_length=500, 56 | end_period_pause=0, 57 | interpolate_period=False, 58 | period_label={'x': .98, 'y': .3, 'ha': 'right', 'va': 'center'}, 59 | period_template='%B %d, %Y', 60 | period_summary_func=lambda v, r: {'x': .98, 'y': .2, 61 | 's': f'Total deaths: {v.sum():,.0f}', 62 | 'ha': 'right', 'size': 11}, 63 | perpendicular_bar_func='median', 64 | colors='dark12', 65 | title='COVID-19 Deaths by Country', 66 | bar_size=.95, 67 | bar_textposition='inside', 68 | bar_texttemplate='{x:,.0f}', 69 | bar_label_font=7, 70 | tick_label_font=7, 71 | tick_template='{x:,.0f}', 72 | shared_fontdict=None, 73 | scale='linear', 74 | fig=None, 75 | writer=None, 76 | bar_kwargs={'alpha': .7}, 77 | fig_kwargs={'figsize': (6, 3.5), 'dpi': 144}, 78 | filter_column_colors=False) 79 | ``` 80 | 81 | ### Save animation to disk or embed into a Jupyter Notebook 82 | 83 | If you are working within a Jupyter Notebook, leave the `filename` as `None` and it will be automatically embedded into a Jupyter Notebook. 84 | 85 | ```python 86 | bcr.bar_chart_race(df=df, filename=None) 87 | ``` 88 | 89 | ![img](https://github.com/dexplo/bar_chart_race/raw/gh-pages/images/bcr_notebook.png) 90 | 91 | ### Customization 92 | 93 | There are many options to customize the bar chart race to get the animation you desire. Below, we have an animation where the maximum x-value and order of the bars are set for the entire duration. A custom summary label and perpendicular bar of the median is also added. 94 | 95 | ```python 96 | def period_summary(values, ranks): 97 | top2 = values.nlargest(2) 98 | leader = top2.index[0] 99 | lead = top2.iloc[0] - top2.iloc[1] 100 | s = f'{leader} by {lead:.0f}' 101 | return {'s': s, 'x': .99, 'y': .03, 'ha': 'right', 'size': 8} 102 | 103 | df_baseball = bcr.load_dataset('baseball').pivot(index='year', 104 | columns='name', 105 | values='hr') 106 | df_baseball.bcr.bar_chart_race( 107 | period_length=1000, 108 | fixed_max=True, 109 | fixed_order=True, 110 | n_bars=10, 111 | period_summary_func=period_summary, 112 | period_label={'x': .99, 'y': .1}, 113 | period_template='Season {x:,.0f}', 114 | title='Top 10 Home Run Hitters by Season Played') 115 | ``` 116 | 117 | ![img](https://github.com/dexplo/bar_chart_race/raw/gh-pages/images/baseball_horiz.gif) 118 | -------------------------------------------------------------------------------- /bar_chart_race/__init__.py: -------------------------------------------------------------------------------- 1 | from ._bar_chart_race import bar_chart_race 2 | import importlib 3 | if importlib.util.find_spec('plotly'): 4 | from ._bar_chart_race_plotly import bar_chart_race_plotly 5 | from ._line_chart_race import line_chart_race 6 | from ._utils import load_dataset, prepare_wide_data, prepare_long_data 7 | from . import _pandas_accessor 8 | 9 | __version__ = '0.2.0' 10 | __all__ = [ 11 | 'bar_chart_race', 12 | 'bar_chart_race_plotly', 13 | 'load_dataset', 14 | 'prepare_wide_data', 15 | 'prepare_long_data', 16 | 'line_chart_race'] 17 | -------------------------------------------------------------------------------- /bar_chart_race/_bar_chart_race_plotly.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | import numpy as np 4 | import pandas as pd 5 | import plotly.graph_objects as go 6 | import plotly 7 | 8 | from ._utils import prepare_wide_data 9 | 10 | 11 | class _BarChartRace: 12 | 13 | def __init__(self, df, filename, orientation, sort, n_bars, fixed_order, fixed_max, 14 | steps_per_period, period_length, end_period_pause, interpolate_period, 15 | period_label, period_template, period_summary_func, perpendicular_bar_func, 16 | colors, title, bar_size, bar_textposition, bar_texttemplate, bar_label_font, 17 | tick_label_font, hovertemplate, slider, scale, bar_kwargs, layout_kwargs, 18 | write_html_kwargs, filter_column_colors): 19 | self.filename = filename 20 | self.extension = self.get_extension() 21 | self.orientation = orientation 22 | self.sort = sort 23 | self.n_bars = n_bars or df.shape[1] 24 | self.fixed_order = fixed_order 25 | self.fixed_max = fixed_max 26 | self.steps_per_period = steps_per_period 27 | self.period_length = period_length 28 | self.end_period_pause = end_period_pause 29 | self.interpolate_period = interpolate_period 30 | self.period_label = self.get_period_label(period_label) 31 | self.period_template = period_template 32 | self.period_summary_func = period_summary_func 33 | self.perpendicular_bar_func = perpendicular_bar_func 34 | self.title = self.get_title(title) 35 | self.bar_size = bar_size 36 | self.bar_textposition = bar_textposition 37 | self.bar_texttemplate = self.get_bar_texttemplate(bar_texttemplate) 38 | self.bar_label_font = self.get_font(bar_label_font) 39 | self.tick_label_font = self.get_font(tick_label_font) 40 | self.hovertemplate = self.get_hovertemplate(hovertemplate) 41 | self.slider = slider 42 | self.scale = scale 43 | self.duration = self.period_length / steps_per_period 44 | self.write_html_kwargs = write_html_kwargs or {} 45 | self.filter_column_colors = filter_column_colors 46 | 47 | self.validate_params() 48 | self.bar_kwargs = self.get_bar_kwargs(bar_kwargs) 49 | self.layout_kwargs = self.get_layout_kwargs(layout_kwargs) 50 | self.df_values, self.df_ranks = self.prepare_data(df) 51 | self.col_filt = self.get_col_filt() 52 | self.bar_colors = self.get_bar_colors(colors) 53 | self.set_fixed_max_limits() 54 | self.str_index = self.df_values.index.astype('str') 55 | 56 | def get_extension(self): 57 | if self.filename: 58 | return self.filename.split('.')[-1] 59 | 60 | def get_bar_texttemplate(self, bar_texttemplate): 61 | if bar_texttemplate is None: 62 | bar_texttemplate = '%{x:,.0f}' if self.orientation == 'h' else '%{y:,.0f}' 63 | return bar_texttemplate 64 | 65 | def validate_params(self): 66 | if isinstance(self.filename, str): 67 | if '.' not in self.filename: 68 | raise ValueError('`filename` must have an extension') 69 | elif self.filename is not None: 70 | raise TypeError('`filename` must be None or a string') 71 | 72 | if self.sort not in ('asc', 'desc'): 73 | raise ValueError('`sort` must be "asc" or "desc"') 74 | 75 | if self.orientation not in ('h', 'v'): 76 | raise ValueError('`orientation` must be "h" or "v"') 77 | 78 | def get_bar_kwargs(self, bar_kwargs): 79 | if bar_kwargs is None: 80 | return {'opacity': .8} 81 | elif isinstance(bar_kwargs, dict): 82 | if 'opacity' not in bar_kwargs: 83 | bar_kwargs['opacity'] = .8 84 | return bar_kwargs 85 | raise TypeError('`bar_kwargs` must be None or a dictionary mapping `go.Bar` parameters ' 86 | 'to values.') 87 | 88 | def get_layout_kwargs(self, layout_kwargs): 89 | if layout_kwargs is None: 90 | return {'showlegend': False} 91 | elif isinstance(layout_kwargs, dict): 92 | if {'xaxis', 'yaxis', 'annotations'} & layout_kwargs.keys(): 93 | raise ValueError('`layout_kwargs` cannot contain "xaxis", "yaxis", or ' 94 | ' "annotations".') 95 | if 'showlegend' not in layout_kwargs: 96 | layout_kwargs['showlegend'] = False 97 | return layout_kwargs 98 | elif isinstance(layout_kwargs, plotly.graph_objs._layout.Layout): 99 | return self.get_layout_kwargs(layout_kwargs.to_plotly_json()) 100 | raise TypeError('`layout_kwargs` must be None, a dictionary mapping ' 101 | '`go.Layout` parameters to values or an instance of `go.Layout`.') 102 | 103 | def get_period_label(self, period_label): 104 | if period_label is False: 105 | return False 106 | 107 | default_period_label = {'xref': 'paper', 'yref': 'paper', 'font': {'size': 20}, 108 | 'xanchor': 'right', 'showarrow': False} 109 | if self.orientation == 'h': 110 | default_period_label['x'] = .95 111 | default_period_label['y'] = .15 if self.sort == 'desc' else .85 112 | else: 113 | default_period_label['x'] = .95 if self.sort == 'desc' else .05 114 | default_period_label['y'] = .85 115 | default_period_label['xanchor'] = 'left' if self.sort == 'asc' else 'right' 116 | 117 | if period_label is True: 118 | return default_period_label 119 | elif isinstance(period_label, dict): 120 | period_label = {**default_period_label, **period_label} 121 | else: 122 | raise TypeError('`period_label` must be a boolean or dictionary') 123 | 124 | return period_label 125 | 126 | def get_title(self, title): 127 | if title is None: 128 | return 129 | if isinstance(title, str): 130 | return {'text': title, 'y': 1, 'x': .5, 'xref': 'paper', 'yref': 'paper', 131 | 'pad': {'b': 10}, 132 | 'xanchor': 'center', 'yanchor': 'bottom'} 133 | elif isinstance(title, (dict, plotly.graph_objects.layout.Title)): 134 | return title 135 | raise TypeError('`title` must be a string, dictionary, or ' 136 | '`plotly.graph_objects.layout.Title` instance') 137 | 138 | def get_font(self, font): 139 | if font is None: 140 | font = {'size': 12} 141 | elif isinstance(font, (int, float)): 142 | font = {'size': font} 143 | elif not isinstance(font, dict): 144 | raise TypeError('`font` must be a number or dictionary of font properties') 145 | return font 146 | 147 | def get_hovertemplate(self, hovertemplate): 148 | if hovertemplate is None: 149 | if self.orientation == 'h': 150 | return '%{y} - %{x:,.0f}' 151 | return '%{x} - %{y:,.0f}' 152 | return hovertemplate 153 | 154 | def prepare_data(self, df): 155 | if self.fixed_order is True: 156 | last_values = df.iloc[-1].sort_values(ascending=False) 157 | cols = last_values.iloc[:self.n_bars].index 158 | df = df[cols] 159 | elif isinstance(self.fixed_order, list): 160 | cols = self.fixed_order 161 | df = df[cols] 162 | self.n_bars = min(len(cols), self.n_bars) 163 | 164 | compute_ranks = self.fixed_order is False 165 | dfs = prepare_wide_data(df, orientation=self.orientation, sort=self.sort, 166 | n_bars=self.n_bars, interpolate_period=self.interpolate_period, 167 | steps_per_period=self.steps_per_period, compute_ranks=compute_ranks) 168 | if isinstance(dfs, tuple): 169 | df_values, df_ranks = dfs 170 | else: 171 | df_values = dfs 172 | 173 | if self.fixed_order: 174 | n = df_values.shape[1] + 1 175 | m = df_values.shape[0] 176 | rank_row = np.arange(1, n) 177 | if (self.sort == 'desc' and self.orientation == 'h') or \ 178 | (self.sort == 'asc' and self.orientation == 'v'): 179 | rank_row = rank_row[::-1] 180 | 181 | ranks_arr = np.repeat(rank_row.reshape(1, -1), m, axis=0) 182 | df_ranks = pd.DataFrame(data=ranks_arr, columns=cols) 183 | 184 | return df_values, df_ranks 185 | 186 | def get_col_filt(self): 187 | col_filt = pd.Series([True] * self.df_values.shape[1]) 188 | if self.n_bars < self.df_ranks.shape[1]: 189 | orient_sort = self.orientation, self.sort 190 | if orient_sort in [('h', 'asc'), ('v', 'desc')]: 191 | # 1 is high 192 | col_filt = (self.df_ranks < self.n_bars + .99).any() 193 | else: 194 | # 1 is low 195 | col_filt = (self.df_ranks > 0).any() 196 | 197 | if self.filter_column_colors and not col_filt.all(): 198 | self.df_values = self.df_values.loc[:, col_filt] 199 | self.df_ranks = self.df_ranks.loc[:, col_filt] 200 | return col_filt 201 | 202 | def get_bar_colors(self, colors): 203 | if colors is None: 204 | colors = 'dark12' 205 | if self.df_values.shape[1] > 10: 206 | colors = 'dark24' 207 | 208 | if isinstance(colors, str): 209 | from ._colormaps import colormaps 210 | try: 211 | bar_colors = colormaps[colors.lower()] 212 | except KeyError: 213 | raise KeyError(f'Colormap {colors} does not exist. Here are the ' 214 | f'possible colormaps: {colormaps.keys()}') 215 | elif isinstance(colors, list): 216 | bar_colors = colors 217 | elif isinstance(colors, tuple): 218 | bar_colors = list(colors) 219 | elif hasattr(colors, 'tolist'): 220 | bar_colors = colors.tolist() 221 | else: 222 | raise TypeError('`colors` must be a string name of a colormap or ' 223 | 'sequence of colors.') 224 | 225 | # bar_colors is now a list 226 | n = len(bar_colors) 227 | orig_bar_colors = bar_colors 228 | if self.df_values.shape[1] > n: 229 | bar_colors = bar_colors * (self.df_values.shape[1] // n + 1) 230 | bar_colors = np.array(bar_colors[:self.df_values.shape[1]]) 231 | 232 | # plotly uses 0, 255 rgb colors, matplotlib is 0 to 1 233 | if bar_colors.dtype.kind == 'f' and bar_colors.shape[1] == 3 and (bar_colors <= 1).all(): 234 | bar_colors = pd.DataFrame(bar_colors).astype('str') 235 | bar_colors = bar_colors.apply(lambda x: ','.join(x), axis = 1) 236 | bar_colors = ('rgb(' + bar_colors + ')').values 237 | 238 | if not self.filter_column_colors: 239 | if not self.col_filt.all(): 240 | col_idx = np.where(self.col_filt)[0] % n 241 | col_idx_ct = np.bincount(col_idx, minlength=n) 242 | num_cols = max(self.col_filt.sum(), n) 243 | exp_ct = np.bincount(np.arange(num_cols) % n, minlength=n) 244 | if (col_idx_ct > exp_ct).any(): 245 | warnings.warn("Some of your columns never make an appearance in the animation. " 246 | "To reduce color repetition, set `filter_column_colors` to `True`") 247 | return bar_colors 248 | 249 | def set_fixed_max_limits(self): 250 | label_limit = (.2, self.n_bars + .8) 251 | value_limit = None 252 | min_val = 1 if self.scale == 'log' else 0 253 | if self.fixed_max: 254 | value_limit = [min_val, self.df_values.max().max() * 1.1] 255 | 256 | if self.orientation == 'h': 257 | self.xlimit = value_limit 258 | self.ylimit = label_limit 259 | else: 260 | self.xlimit = label_limit 261 | self.ylimit = value_limit 262 | 263 | def set_value_limit(self, bar_vals): 264 | min_val = 1 if self.scale == 'log' else 0 265 | if not self.fixed_max: 266 | value_limit = [min_val, bar_vals.max() * 1.1] 267 | 268 | if self.orientation == 'h': 269 | self.xlimit = value_limit 270 | else: 271 | self.ylimit = value_limit 272 | 273 | def get_frames(self): 274 | frames = [] 275 | slider_steps = [] 276 | for i in range(len(self.df_values)): 277 | bar_locs = self.df_ranks.iloc[i].values 278 | top_filt = (bar_locs >= 0) & (bar_locs < self.n_bars + 1) 279 | bar_vals = self.df_values.iloc[i].values 280 | bar_vals[bar_locs == 0] = 0 281 | bar_vals[bar_locs == self.n_bars + 1] = 0 282 | # self.set_value_limit(bar_vals) # plotly bug? not updating range 283 | 284 | cols = self.df_values.columns.values.copy() 285 | cols[bar_locs == 0] = ' ' 286 | colors = self.bar_colors 287 | bar_locs = bar_locs + np.random.rand(len(bar_locs)) / 10_000 # done to prevent stacking of bars 288 | x, y = (bar_vals, bar_locs) if self.orientation == 'h' else (bar_locs, bar_vals) 289 | 290 | label_axis = dict(tickmode='array', tickvals=bar_locs, ticktext=cols, 291 | tickfont=self.tick_label_font) 292 | 293 | label_axis['range'] = self.ylimit if self.orientation == 'h' else self.xlimit 294 | if self.orientation == 'v': 295 | label_axis['tickangle'] = -90 296 | 297 | value_axis = dict(showgrid=True, type=self.scale)#, tickformat=',.0f') 298 | value_axis['range'] = self.xlimit if self.orientation == 'h' else self.ylimit 299 | 300 | bar = go.Bar(x=x, y=y, width=self.bar_size, textposition=self.bar_textposition, 301 | texttemplate=self.bar_texttemplate, orientation=self.orientation, 302 | marker_color=colors, insidetextfont=self.bar_label_font, 303 | cliponaxis=False, outsidetextfont=self.bar_label_font, 304 | hovertemplate=self.hovertemplate, **self.bar_kwargs) 305 | 306 | data = [bar] 307 | xaxis, yaxis = (value_axis, label_axis) if self.orientation == 'h' \ 308 | else (label_axis, value_axis) 309 | 310 | annotations = self.get_annotations(i) 311 | if self.slider and i % self.steps_per_period == 0: 312 | slider_steps.append( 313 | {"args": [[i], 314 | {"frame": {"duration": self.duration, "redraw": False}, 315 | "mode": "immediate", 316 | "fromcurrent": True, 317 | "transition": {"duration": self.duration} 318 | }], 319 | "label": self.get_period_label_text(i), 320 | "method": "animate"}) 321 | layout = go.Layout(xaxis=xaxis, yaxis=yaxis, annotations=annotations, 322 | margin={'l': 150}, **self.layout_kwargs) 323 | if self.perpendicular_bar_func: 324 | pbar = self.get_perpendicular_bar(bar_vals, i, layout) 325 | layout.update(shapes=[pbar], overwrite=True) 326 | frames.append(go.Frame(data=data, layout=layout, name=i)) 327 | 328 | return frames, slider_steps 329 | 330 | def get_period_label_text(self, i): 331 | if self.period_template: 332 | idx_val = self.df_values.index[i] 333 | if self.df_values.index.dtype.kind == 'M': 334 | s = idx_val.strftime(self.period_template) 335 | else: 336 | s = self.period_template.format(x=idx_val) 337 | else: 338 | s = self.str_index[i] 339 | return s 340 | 341 | def get_annotations(self, i): 342 | annotations = [] 343 | if self.period_label: 344 | self.period_label['text'] = self.get_period_label_text(i) 345 | annotations.append(self.period_label) 346 | 347 | if self.period_summary_func: 348 | values = self.df_values.iloc[i] 349 | ranks = self.df_ranks.iloc[i] 350 | text_dict = self.period_summary_func(values, ranks) 351 | if 'x' not in text_dict or 'y' not in text_dict or 'text' not in text_dict: 352 | name = self.period_summary_func.__name__ 353 | raise ValueError(f'The dictionary returned from `{name}` must contain ' 354 | '"x", "y", and "s"') 355 | text, x, y = text_dict['text'], text_dict['x'], text_dict['y'] 356 | annotations.append(dict(text=text, x=x, y=y, font=dict(size=14), 357 | xref="paper", yref="paper", showarrow=False)) 358 | 359 | return annotations 360 | 361 | def get_perpendicular_bar(self, bar_vals, i, layout): 362 | if isinstance(self.perpendicular_bar_func, str): 363 | val = pd.Series(bar_vals).agg(self.perpendicular_bar_func) 364 | else: 365 | values = self.df_values.iloc[i] 366 | ranks = self.df_ranks.iloc[i] 367 | val = self.perpendicular_bar_func(values, ranks) 368 | 369 | xref, yref = ("x", "paper") if self.orientation == 'h' else ("paper", "y") 370 | value_limit = self.xlimit if self.orientation == 'h' else self.ylimit 371 | if self.fixed_max: 372 | delta = (value_limit[1] - value_limit[0]) * .02 373 | else: 374 | delta = (1.05 * bar_vals.max() - bar_vals.min()) * .02 375 | 376 | x0, x1 = (val - delta, val + delta) if self.orientation == 'h' else (0, 1) 377 | y0, y1 = (val - delta, val + delta) if self.orientation == 'v' else (0, 1) 378 | 379 | return dict(type="rect", xref=xref, yref=yref, x0=x0, y0=y0, x1=x1, y1=y1, 380 | fillcolor="#444444",layer="below", opacity=.5, line_width=0) 381 | 382 | def make_animation(self): 383 | frames, slider_steps = self.get_frames() 384 | data = frames[0].data 385 | layout = frames[0].layout 386 | layout.title = self.title 387 | layout.updatemenus = [dict( 388 | type="buttons", 389 | direction = "left", 390 | x=1, 391 | y=1.02, 392 | xanchor='right', 393 | yanchor='bottom', 394 | buttons=[dict(label="Play", 395 | method="animate", 396 | # redraw must be true for bar plots 397 | args=[None, {"frame": {"duration": self.duration, "redraw": True}, 398 | "fromcurrent": True 399 | }]), 400 | dict(label="Pause", 401 | method="animate", 402 | args=[[None], {"frame": {"duration": 0, "redraw": False}, 403 | "mode": "immediate", 404 | "transition": {"duration": 0}}]), 405 | ] 406 | )] 407 | 408 | sliders_dict = { 409 | "active": 0, 410 | "yanchor": "top", 411 | "xanchor": "left", 412 | "currentvalue": { 413 | # "font": {"size": 20}, 414 | # "prefix": '', # allow user to set 415 | "visible": False, # just repeats period label 416 | # "xanchor": "right" 417 | }, 418 | "transition": {"duration": self.duration, "easing": "cubic-in-out"}, 419 | "pad": {"b": 10, "t": 50}, 420 | "len": 0.88, 421 | "x": 0.05, 422 | "y": 0, 423 | "steps": slider_steps 424 | } 425 | if self.slider: 426 | layout.sliders = [sliders_dict] 427 | 428 | fig = go.Figure(data=data, layout=layout, frames=frames[1:]) 429 | if self.filename: 430 | fig.write_html(self.filename, **self.write_html_kwargs) 431 | else: 432 | return fig 433 | 434 | 435 | def bar_chart_race_plotly(df, filename=None, orientation='h', sort='desc', n_bars=None, 436 | fixed_order=False, fixed_max=False, steps_per_period=10, 437 | period_length=500, end_period_pause=0, interpolate_period=False, 438 | period_label=True, period_template=None, period_summary_func=None, 439 | perpendicular_bar_func=None, colors=None, title=None, bar_size=.95, 440 | bar_textposition='outside', bar_texttemplate=None, bar_label_font=None, 441 | tick_label_font=None, hovertemplate=None, slider=True, scale='linear', 442 | bar_kwargs=None, layout_kwargs=None, write_html_kwargs=None, 443 | filter_column_colors=False): 444 | ''' 445 | Create an animated bar chart race using Plotly. Data must be in 446 | 'wide' format where each row represents a single time period and each 447 | column represents a distinct category. Optionally, the index can label 448 | the time period. Bar length and location change linearly from one time 449 | period to the next. 450 | 451 | Note - The duration of each frame is calculated as 452 | `period_length` / `steps_per_period`, but is unlikely to actually 453 | be this number, especially when duration is low (< 50ms). You may have to 454 | experiment with different combinations of `period_length` and 455 | `steps_per_period` to get the animation at the desired speed. 456 | 457 | If no `filename` is given, a plotly figure is returned that is embedded 458 | into the notebook. 459 | 460 | Parameters 461 | ---------- 462 | df : pandas DataFrame 463 | Must be a 'wide' DataFrame where each row represents a single period 464 | of time. Each column contains the values of the bars for that 465 | category. Optionally, use the index to label each time period. 466 | The index can be of any type. 467 | 468 | filename : `None` or str, default None 469 | If `None` return plotly animation, otherwise save 470 | to disk. Can only save as HTML at this time. 471 | 472 | orientation : 'h' or 'v', default 'h' 473 | Bar orientation - horizontal or vertical 474 | 475 | sort : 'desc' or 'asc', default 'desc' 476 | Choose how to sort the bars. Use 'desc' to put largest bars on top 477 | and 'asc' to place largest bars on bottom. 478 | 479 | n_bars : int, default None 480 | Choose the maximum number of bars to display on the graph. 481 | By default, use all bars. New bars entering the race will appear 482 | from the edge of the axes. 483 | 484 | fixed_order : bool or list, default False 485 | When `False`, bar order changes every time period to correspond 486 | with `sort`. When `True`, bars remained fixed according to their 487 | final value corresponding with `sort`. Otherwise, provide a list 488 | of the exact order of the categories for the entire duration. 489 | 490 | fixed_max : bool, default False 491 | Whether to fix the maximum value of the axis containing the values. 492 | When `False`, the axis for the values will have its maximum (x/y) 493 | just after the largest bar of the current time period. 494 | The axis maximum will change along with the data. 495 | 496 | When True, the maximum axis value will remain constant for the 497 | duration of the animation. For example, in a horizontal bar chart, 498 | if the largest bar has a value of 100 for the first time period and 499 | 10,000 for the last time period. The xlim maximum will be 10,000 500 | for each frame. 501 | 502 | steps_per_period : int, default 10 503 | The number of steps to go from one time period to the next. 504 | The bars will grow linearly between each period. 505 | 506 | period_length : int, default 500 507 | Number of milliseconds to animate each period (row). 508 | Default is 500ms (half of a second) 509 | 510 | end_period_pause : int, default 0 511 | Number of milliseconds to pause the animation at the end of 512 | each period. 513 | 514 | interpolate_period : bool, default `False` 515 | Whether to interpolate the period. Only valid for datetime or 516 | numeric indexes. When set to `True`, for example, 517 | the two consecutive periods 2020-03-29 and 2020-03-30 with 518 | `steps_per_period` set to 4 would yield a new index of 519 | 2020-03-29 00:00:00 520 | 2020-03-29 06:00:00 521 | 2020-03-29 12:00:00 522 | 2020-03-29 18:00:00 523 | 2020-03-30 00:00:00 524 | 525 | period_label : bool or dict, default `True` 526 | If `True` or dict, use the index as a large text label 527 | on the figure labeling each period. No label when 'False'. 528 | 529 | Use a dictionary to supply the exact position of the period 530 | along with any valid parameters of a plotly annotation. 531 | 532 | Example: 533 | { 534 | 'x': .99, 535 | 'y': .8, 536 | 'font' : {'family': 'Helvetica', 'size': 20, 'color': 'orange'}, 537 | 'xanchor': 'right', 538 | } 539 | 540 | Reference - https://plotly.com/python/reference/#layout-annotations 541 | 542 | The default location depends on `orientation` and `sort` 543 | * h, desc -> x=.95, y=.15 544 | * h, asc -> x=.95, y=.85 545 | * v, desc -> x=.95, y=.85 546 | * v, asc -> x=.05, y=.85 547 | 548 | period_template : str, default `None` 549 | Either a string with date directives or 550 | a new-style (Python 3.6+) formatted string 551 | 552 | For a string with a date directive, find the complete list here 553 | https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes 554 | 555 | Example of string with date directives 556 | '%B %d, %Y' 557 | Will change 2020/03/29 to March 29, 2020 558 | 559 | For new-style formatted string. Use curly braces and the variable `x`, 560 | which will be passed the current period's index value. 561 | Example: 562 | 'Period {x:10.2f}' 563 | 564 | Date directives will only be used for datetime indexes. 565 | 566 | period_summary_func : function, default None 567 | Custom text added to the axes each period. 568 | Create a user-defined function that accepts two pandas Series of the 569 | current time period's values and ranks. It must return a dictionary 570 | containing at a minimum the keys "x", "y", and "text" which will be 571 | passed used for a plotly annotation. 572 | 573 | Example: 574 | def func(values, ranks): 575 | total = values.sum() 576 | text = f'Worldwide deaths: {total}' 577 | return {'x': .85, 'y': .2, 'text': text, 'size': 11} 578 | 579 | perpendicular_bar_func : function or str, default None 580 | Creates a single bar perpendicular to the main bars that spans the 581 | length of the axis. 582 | 583 | Use either a string that the DataFrame `agg` method understands or a 584 | user-defined function. 585 | 586 | DataFrame strings - 'mean', 'median', 'max', 'min', etc.. 587 | 588 | The function is passed two pandas Series of the current time period's 589 | data and ranks. It must return a single value. 590 | 591 | def func(values, ranks): 592 | return values.quantile(.75) 593 | 594 | colors : str or sequence colors, default 'dark12' 595 | Colors to be used for the bars. All matplotlib and plotly colormaps are 596 | available by string name. Colors will repeat if there are more bars than colors. 597 | 598 | 'dark12' is the default colormap. If there are more than 10 columns, 599 | then the default colormap will be 'dark24' 600 | 601 | Append "_r" to the colormap name to use the reverse of the colormap. 602 | i.e. "dark12_r" 603 | 604 | title : str, dict, or plotly.graph_objects.layout.Title , default None 605 | Title of animation. Use a string for simple titles or a 606 | dictionary to specify several properties 607 | {'text': 'My Bar Chart Race', 608 | 'x':0.5, 609 | 'y':.9, 610 | 'xanchor': 'center', 611 | 'yanchor': 'bottom'} 612 | 613 | Other properties include: font, pad, xref, yref 614 | 615 | bar_size : float, default .95 616 | Height/width of bars for horizontal/vertical bar charts. 617 | Use a number between 0 and 1 618 | Represents the fraction of space that each bar takes up. 619 | When equal to 1, no gap remains between the bars. 620 | 621 | bar_textposition : str or sequence, default `None` 622 | Position on bar to place its label. 623 | Use one of the strings - 'inside', 'outside', 'auto', 'none' 624 | or a sequence of the above 625 | 626 | bar_texttemplate : str, default '%{x:,.0f}' or '%{y:,.0f}' 627 | Template string used for rendering the text inside/outside 628 | the bars. Variables are inserted using %{variable}, 629 | for example "y: %{y}". Numbers are formatted using 630 | d3-format's syntax %{variable:d3-format}, for example 631 | "Price: %{y:$.2f}". 632 | 633 | bar_label_font : number or dict, None 634 | Font size of numeric bar labels. When None, font size is 12. 635 | Use a dictionary to supply several font properties. 636 | Example: 637 | { 638 | 'size': 12, 639 | 'family': 'Courier New, monospace', 640 | 'color': '#7f7f7f' 641 | } 642 | 643 | tick_label_font : number or dict, None 644 | Font size of tick labels.When None, font size is 12. 645 | Use a dictionary to supply several font properties. 646 | 647 | hovertemplate : str, default None 648 | Template string used for rendering the information that appear 649 | on hover box. By default, it is '%{y} - %{x:,.0f}' 650 | 651 | Reference: https://plotly.com/python/hover-text-and-formatting 652 | 653 | slider : bool, default True 654 | Whether or not to place a slider below the animation 655 | 656 | scale : 'linear' or 'log', default 'linear' 657 | Type of scaling to use for the axis containing the values 658 | 659 | bar_kwargs : dict, default `None` (opacity=.8) 660 | Other keyword arguments (within a dictionary) forwarded to the 661 | plotly `go.Bar` function. If no value for 'opacity' is given, 662 | then it is set to .8 by default. 663 | 664 | layout_kwargs : dict or go.Layout instance, default None 665 | Other keyword arguments (within a dictionary) are forwarded to 666 | the plotly `go.Layout` function. Use this to control the size of 667 | the figure. 668 | Example: 669 | { 670 | 'width': 600, 671 | 'height': 400, 672 | 'showlegend': True 673 | } 674 | 675 | write_html_kwargs : dict, default None 676 | Arguments passed to the write_html plotly go.Figure method. 677 | Example: 678 | { 679 | 'auto_play': False, 680 | 'include_plotlyjs': 'cdn', 681 | 'full_html': False= 682 | } 683 | Reference: https://plotly.github.io/plotly.py-docs/generated/plotly.io.write_html.html 684 | 685 | filter_column_colors : bool, default `False` 686 | When setting n_bars, it's possible that some columns never 687 | appear in the animation. Regardless, all columns get assigned 688 | a color by default. 689 | 690 | For instance, suppose you have 100 columns 691 | in your DataFrame, set n_bars to 10, and 15 different columns 692 | make at least one appearance in the animation. Even if your 693 | colormap has at least 15 colors, it's possible that many 694 | bars will be the same color, since each of the 100 columns is 695 | assigned of the colormaps colors. 696 | 697 | Setting this to `True` will map your colormap to just those 698 | columns that make an appearance in the animation, helping 699 | avoid duplication of colors. 700 | 701 | Setting this to `True` will also have the (possibly unintended) 702 | consequence of changing the colors of each color every time a 703 | new integer for n_bars is used. 704 | 705 | EXPERIMENTAL 706 | This parameter is experimental and may be changed/removed 707 | in a later version. 708 | 709 | Returns 710 | ------- 711 | When `filename` is left as `None`, a plotly figure is returned and 712 | embedded into the notebook. Otherwise, a file of the HTML is 713 | saved and `None` is returned. 714 | 715 | References 716 | ----- 717 | Plotly Figure - https://plotly.com/python/reference 718 | Plotly API - https://plotly.com/python-api-reference 719 | d3 formatting - https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md 720 | 721 | Examples 722 | -------- 723 | Use the `load_data` function to get an example dataset to 724 | create an animation. 725 | 726 | df = bcr.load_dataset('covid19') 727 | bcr.bar_chart_race_plotly( 728 | df=df, 729 | filename='covid19_horiz_desc.html', 730 | orientation='h', 731 | sort='desc', 732 | n_bars=8, 733 | fixed_order=False, 734 | fixed_max=True, 735 | steps_per_period=10, 736 | period_length=500, 737 | interpolate_period=False, 738 | period_label={'x': .99, 'y': .8, 'font': {'size': 25, 'color': 'blue'}}, 739 | period_template='%B %d, %Y', 740 | period_summary_func=lambda v, r: {'x': .85, 'y': .2, 741 | 's': f'Total deaths: {v.sum()}', 742 | 'size': 11}, 743 | perpendicular_bar_func='median', 744 | colors='dark12', 745 | title='COVID-19 Deaths by Country', 746 | bar_size=.95, 747 | bar_textposition='outside', 748 | bar_texttemplate='%{x}', 749 | bar_label_font=12, 750 | tick_label_font=12, 751 | hovertemplate=None, 752 | scale='linear', 753 | bar_kwargs={'opacity': .7}, 754 | write_html_kwargs=None, 755 | filter_column_colors=False) 756 | ''' 757 | bcr = _BarChartRace(df, filename, orientation, sort, n_bars, fixed_order, fixed_max, 758 | steps_per_period, period_length, end_period_pause, interpolate_period, 759 | period_label, period_template, period_summary_func, perpendicular_bar_func, 760 | colors, title, bar_size, bar_textposition, bar_texttemplate, bar_label_font, 761 | tick_label_font, hovertemplate, slider, scale, bar_kwargs, layout_kwargs, 762 | write_html_kwargs, filter_column_colors) 763 | return bcr.make_animation() 764 | -------------------------------------------------------------------------------- /bar_chart_race/_codes/code_value.csv: -------------------------------------------------------------------------------- 1 | code,value 2 | country,https://github.com/hjnilsson/country-flags/raw/master/png250px/{code}.png 3 | nfl,self -------------------------------------------------------------------------------- /bar_chart_race/_codes/country.csv: -------------------------------------------------------------------------------- 1 | code,value 2 | ad,ad 3 | and,ad 4 | andorra,ad 5 | principality of andorra,ad 6 | principality of the valleys of andorra,ad 7 | principat d'andorra,ad 8 | ae,ae 9 | al emirat al arabbiya al muttahida,ae 10 | are,ae 11 | the emirates,ae 12 | trucial states,ae 13 | u.a.e,ae 14 | uae,ae 15 | united arab emirates,ae 16 | af,af 17 | afghanistan,af 18 | da afġānistān islāmī jumhoryat,af 19 | islamic republic of afghanistan,af 20 | jomhūrīyyeh eslāmīyyeh afġānestān,af 21 | ag,ag 22 | antigua and barbuda,ag 23 | atg,ag 24 | ai,ai 25 | aia,ai 26 | anguilla,ai 27 | al,al 28 | alb,al 29 | albania,al 30 | arbanon,al 31 | arnavutluk,al 32 | republic of albania,al 33 | republika e shqipërisë,al 34 | am,am 35 | arm,am 36 | armenia,am 37 | hayastan,am 38 | republic of armenia,am 39 | ago,ao 40 | angola,ao 41 | ao,ao 42 | antarctica,aq 43 | aq,aq 44 | ata,aq 45 | ar,ar 46 | arg,ar 47 | argentina,ar 48 | argentine confederation,ar 49 | argentine nation,ar 50 | argentine republic,ar 51 | la argentina,ar 52 | the argentine,ar 53 | united provinces of the río de la plata,ar 54 | american samoa,as 55 | as,as 56 | asm,as 57 | at,at 58 | austria,at 59 | aut,at 60 | republic of austria,at 61 | republik österreich,at 62 | österreich,at 63 | au,au 64 | aus,au 65 | australia,au 66 | commonwealth of australia,au 67 | new holland,au 68 | abw,aw 69 | aruba,aw 70 | aw,aw 71 | ala,ax 72 | ax,ax 73 | åland islands,ax 74 | åland,ax 75 | aland,ax 76 | aland islands,ax 77 | az,az 78 | aze,az 79 | azerbaijan,az 80 | azərbaycan respublikası,az 81 | republic of azerbaijan,az 82 | ba,ba 83 | bih,ba 84 | bosnia and herzegovina,ba 85 | republic of bosnia and herzegovina,ba 86 | socialist republic of bosnia and herzegovina,ba 87 | barbados,bb 88 | bb,bb 89 | bimshire,bb 90 | brb,bb 91 | bangladesh,bd 92 | bd,bd 93 | bengal presidency,bd 94 | bgd,bd 95 | east bengal,bd 96 | east pakistan,bd 97 | people's republic of bangladesh,bd 98 | be,be 99 | bel,be 100 | belgium,be 101 | kingdom of belgium,be 102 | koninkrijk belgië,be 103 | königreich belgien,be 104 | royaume de belgique,be 105 | bf,bf 106 | bfa,bf 107 | bourkina-fasso,bf 108 | burkina faso,bf 109 | haute-volta,bf 110 | upper volta,bf 111 | bg,bg 112 | bgr,bg 113 | bulgaria,bg 114 | people's republic of bulgaria,bg 115 | republic of bulgaria,bg 116 | republika bǎlgariya,bg 117 | bahrain,bh 118 | bh,bh 119 | bhr,bh 120 | kingdom of bahrain,bh 121 | mamlakat al-baḥrayn,bh 122 | state of bahrain,bh 123 | bdi,bi 124 | bi,bi 125 | burundi,bi 126 | kingdom of burundi,bi 127 | republic of burundi,bi 128 | republika y'uburundi,bi 129 | république du burundi,bi 130 | ben,bj 131 | benin,bj 132 | bj,bj 133 | dahomey,bj 134 | republic of benin,bj 135 | république du bénin,bj 136 | blm,bl 137 | saint barthélemy,bl 138 | bl,bl 139 | bermuda,bm 140 | bm,bm 141 | bmu,bm 142 | bn,bn 143 | brn,bn 144 | brunei,bn 145 | brunei darussalam,bn 146 | negara brunei darussalam,bn 147 | state of brunei,bn 148 | نڬارا بروني دارالسلام‎,bn 149 | bo,bo 150 | bol,bo 151 | bolivia,bo 152 | estado plurinacional de bolivia,bo 153 | plurinational state of bolivia,bo 154 | republic of bolivia,bo 155 | republic of bolívar,bo 156 | bes,bq 157 | bq,bq 158 | sint eustatius,bq 159 | br,br 160 | bra,br 161 | brazil,br 162 | empire of brazil,br 163 | federative republic of brazil,br 164 | ilha de vera cruz,br 165 | pindorama,br 166 | república federativa do brasil,br 167 | terra de santa cruz,br 168 | terra di papaga,br 169 | united states of brazil,br 170 | bahamas,bs 171 | bhs,bs 172 | bs,bs 173 | commonwealth of the bahamas,bs 174 | the bahamas,bs 175 | bhutan,bt 176 | bt,bt 177 | btn,bt 178 | druk gyal khap,bt 179 | kingdom of bhutan,bt 180 | bouvet island,bv 181 | bv,bv 182 | bvt,bv 183 | bechuanaland,bw 184 | botswana,bw 185 | bw,bw 186 | bwa,bw 187 | republic of botswana,bw 188 | belarus,by 189 | blr,by 190 | by,by 191 | byelorussia,by 192 | gudija,by 193 | republic of belarus,by 194 | white russia,by 195 | belize,bz 196 | blz,bz 197 | british honduras,bz 198 | bz,bz 199 | ca,ca 200 | can,ca 201 | canada,ca 202 | dominion du canada,ca 203 | dominion of canada,ca 204 | cck,cc 205 | cc,cc 206 | cocos islands,cc 207 | cocos (keeling) islands,cc 208 | keeling islands,cc 209 | territory of cocos islands,cc 210 | belgian congo,cd 211 | cd,cd 212 | cod,cd 213 | congo belge,cd 214 | congo free state,cd 215 | congo kinshasa,cd 216 | democratic republic of congo,cd 217 | congo (kinshasa),cd 218 | drc,cd 219 | zaire,cd 220 | caf,cf 221 | central african empire,cf 222 | central african republic,cf 223 | cf,cf 224 | empire centrafricain,cf 225 | oubangui-chari,cf 226 | république centrafricaine,cf 227 | ubangi-shari,cf 228 | cg,cg 229 | cog,cg 230 | congo,cg 231 | congo brazzaville,cg 232 | french congo,cg 233 | republic of the congo,cg 234 | congo (brazzaville),cg 235 | the congo,cg 236 | ch,ch 237 | che,ch 238 | confederazione svizzera,ch 239 | confederaziun svizra,ch 240 | confédération suisse,ch 241 | schweiz,ch 242 | schweizerische eidgenossenschaft,ch 243 | suisse,ch 244 | svizra,ch 245 | svizzera,ch 246 | swiss confederation,ch 247 | switzerland,ch 248 | ci,ci 249 | civ,ci 250 | côte d'ivoire,ci 251 | ivory coast,ci 252 | cote d'ivoire,ci 253 | republic of côte d'ivoire,ci 254 | république de côte d'ivoire,ci 255 | the ivory coast,ci 256 | cok,ck 257 | ck,ck 258 | cook islands,ck 259 | capitania general de chile,cl 260 | chile,cl 261 | chili,cl 262 | chilli,cl 263 | chl,cl 264 | cl,cl 265 | republic of chile,cl 266 | reyno de chile,cl 267 | cameroon,cm 268 | cm,cm 269 | cmr,cm 270 | kamerun,cm 271 | republic of cameroon,cm 272 | united republic of cameroon,cm 273 | china,cn 274 | chn,cn 275 | cn,cn 276 | communist china,cn 277 | people's republic of china,cn 278 | red china,cn 279 | co,co 280 | col,co 281 | colombia,co 282 | confederación granadina,co 283 | estados unidos de colombia,co 284 | republic of colombia,co 285 | república de colombia,co 286 | república de la nueva granada,co 287 | costa rica,cr 288 | cr,cr 289 | cri,cr 290 | republic of costa rica,cr 291 | república de costa rica,cr 292 | cu,cu 293 | cub,cu 294 | cuba,cu 295 | republic of cuba,cu 296 | república de cuba,cu 297 | cabo verde,cv 298 | cape verde,cv 299 | cpv,cv 300 | cv,cv 301 | curaçao,cw 302 | cuw,cw 303 | cw,cw 304 | christmas island,cx 305 | cx,cx 306 | cxr,cx 307 | cy,cy 308 | cyp,cy 309 | cyprus,cy 310 | bohemia,cz 311 | cz,cz 312 | cze,cz 313 | czech republic,cz 314 | czechia,cz 315 | czechland,cz 316 | koruna česká,cz 317 | the czechlands,cz 318 | čechy a morava,cz 319 | česko,cz 320 | česká konfederace,cz 321 | česká republika,cz 322 | alemania,de 323 | allemagne,de 324 | bundesrepublik deutschland,de 325 | de,de 326 | deu,de 327 | deutschland,de 328 | federal republic of germany,de 329 | german democratic republic,de 330 | germania,de 331 | germany,de 332 | dj,dj 333 | dji,dj 334 | djibouti,dj 335 | republic of djibouti,dj 336 | république de djibouti,dj 337 | danmark,dk 338 | denmark,dk 339 | dk,dk 340 | dnk,dk 341 | kingdom of denmark,dk 342 | kongeriget danmark,dk 343 | dm,dm 344 | dma,dm 345 | dominica,dm 346 | do,do 347 | dom,do 348 | dominican republic,do 349 | al-jazā’ir,dz 350 | algeria,dz 351 | dz,dz 352 | dza,dz 353 | people's democratic republic of algeria,dz 354 | ec,ec 355 | ecu,ec 356 | ecuador,ec 357 | ee,ee 358 | eesti,ee 359 | est,ee 360 | estland,ee 361 | estonia,ee 362 | aegyptus,eg 363 | arab republic of egypt,eg 364 | eg,eg 365 | egy,eg 366 | egypt,eg 367 | esh,eh 368 | western sahara,eh 369 | the sahrawi arab democratic republic,eh 370 | er,er 371 | eri,er 372 | eritrea,er 373 | es,es 374 | esp,es 375 | espainia,es 376 | espanya,es 377 | españa,es 378 | kingdom of spain,es 379 | spain,es 380 | spanish state,es 381 | abyssinia,et 382 | al-habasha,et 383 | et,et 384 | eth,et 385 | ethiopia,et 386 | ethiopië,et 387 | federal democratic republic of ethiopia,et 388 | habeshastan,et 389 | fi,fi 390 | fin,fi 391 | finland,fi 392 | republic of finland,fi 393 | republiken finland,fi 394 | soome,fi 395 | suomen tasavalta,fi 396 | suomenmaa,fi 397 | suomi,fi 398 | suomâ and suomâ täsiväldi,fi 399 | suopma and suoma dásseváldi,fi 400 | fiji,fj 401 | fj,fj 402 | fji,fj 403 | falkland islands,fk 404 | fk,fk 405 | flk,fk 406 | fm,fm 407 | fsm,fm 408 | micronesia,fm 409 | fro,fo 410 | fo,fo 411 | faroe,fo 412 | faroe islands,fo 413 | the faroe,fo 414 | the faroe islands,fo 415 | farança,fr 416 | fr,fr 417 | fra,fr 418 | france,fr 419 | french republic,fr 420 | gaul,fr 421 | gaule,fr 422 | l'hexagone,fr 423 | république française,fr 424 | tsarfat,fr 425 | γαλλία,fr 426 | ga,ga 427 | gab,ga 428 | gabon,ga 429 | gabonese republic,ga 430 | anglia,gb 431 | britain,gb 432 | britannia,gb 433 | caledonia,gb 434 | gb,gb 435 | gbr,gb 436 | great britain,gb 437 | u.k.,gb 438 | uk,gb 439 | united kingdom,gb 440 | united kingdom of great britain and northern ireland,gb 441 | gd,gd 442 | grd,gd 443 | grenada,gd 444 | colchis,ge 445 | ge,ge 446 | geo,ge 447 | georgia,ge 448 | iveria,ge 449 | republic of georgia,ge 450 | گرجستان,ge 451 | french guiana,gf 452 | gf,gf 453 | guf,gf 454 | gg,gg 455 | ggy,gg 456 | guernsey,gg 457 | gaana,gh 458 | gh,gh 459 | gha,gh 460 | ghana,gh 461 | ghana tiŋzuɣu,gh 462 | gold coast,gh 463 | united gold coast convention,gh 464 | gi,gi 465 | gib,gi 466 | gibraltar,gi 467 | gl,gl 468 | greenland,gl 469 | grl,gl 470 | gm,gm 471 | gmb,gm 472 | the gambia,gm 473 | gambia,gm 474 | gambia (the),gm 475 | the republic of gambia,gm 476 | gin,gn 477 | gn,gn 478 | guinea,gn 479 | glp,gp 480 | gp,gp 481 | guadeloupe,gp 482 | equatorial guinea,gq 483 | gnq,gq 484 | gq,gq 485 | gr,gr 486 | grc,gr 487 | greece,gr 488 | hellas,gr 489 | hellenic republic,gr 490 | yavan,gr 491 | yunanistan,gr 492 | ελλάδα,gr 493 | ελλάς,gr 494 | sgs,gs 495 | gs,gs 496 | south georgia and the south sandwich islands,gs 497 | gt,gt 498 | gtm,gt 499 | guatemala,gt 500 | gu,gu 501 | guam,gu 502 | gum,gu 503 | gnb,gw 504 | guinea-bissau,gw 505 | guiné-bissao,gw 506 | gw,gw 507 | portuguese guinea,gw 508 | republic of guinea-bissau,gw 509 | guy,gy 510 | guyana,gy 511 | gy,gy 512 | hk,hk 513 | hkg,hk 514 | hong kong,hk 515 | hmd,hm 516 | hm,hm 517 | heard island and mcdonald islands,hm 518 | territory of heard island and mcdonald islands,hm 519 | hn,hn 520 | hnd,hn 521 | honduras,hn 522 | croatia,hr 523 | hr,hr 524 | hrv,hr 525 | hrvatska,hr 526 | hrvaška,hr 527 | republic of croatia,hr 528 | republika hrvatska,hr 529 | haiti,ht 530 | ht,ht 531 | hti,ht 532 | hu,hu 533 | hun,hu 534 | hungaria,hu 535 | hungarian people's republic,hu 536 | hungary,hu 537 | kingdom of hungary,hu 538 | magyar királyság,hu 539 | magyar köztársaság,hu 540 | magyar népköztársaság,hu 541 | magyar tanácsköztársaság,hu 542 | magyarország,hu 543 | regnum hungariæ,hu 544 | republic of hungary,hu 545 | hindia belanda,id 546 | id,id 547 | idn,id 548 | indonesia,id 549 | indonesië,id 550 | indunesia,id 551 | insulinde,id 552 | nederlands,id 553 | nusantara,id 554 | republic of indonesia,id 555 | republik indonesia,id 556 | hibernia,ie 557 | ie,ie 558 | ireland,ie 559 | irish free state,ie 560 | irl,ie 561 | republic of ireland,ie 562 | herzlstan,il 563 | il,il 564 | isr,il 565 | israel,il 566 | state of israel,il 567 | yehuda,il 568 | imn,im 569 | im,im 570 | isle of man,im 571 | hindustan,in 572 | in,in 573 | ind,in 574 | india,in 575 | republic of india,in 576 | union of india,in 577 | भारत,in 578 | भारतवर्ष,in 579 | iot,io 580 | io,io 581 | british indian ocean territory,io 582 | assyria,iq 583 | babylon,iq 584 | iq,iq 585 | iraq,iq 586 | irq,iq 587 | mesopotamia,iq 588 | ir,ir 589 | iran,ir 590 | irn,ir 591 | islamic republic of iran,ir 592 | persia,ir 593 | iceland,is 594 | is,is 595 | isl,is 596 | lýðveldið ísland,is 597 | republic of iceland,is 598 | it,it 599 | ita,it 600 | italia,it 601 | italy,it 602 | repubblica italiana,it 603 | the beautiful country,it 604 | the boot,it 605 | je,je 606 | jersey,je 607 | jey,je 608 | jam,jm 609 | jamaica,jm 610 | jm,jm 611 | xamayca,jm 612 | hashemite kingdom of jordan,jo 613 | jo,jo 614 | jor,jo 615 | jordan,jo 616 | japan,jp 617 | jp,jp 618 | jpn,jp 619 | nihon,jp 620 | nippon,jp 621 | yamato,jp 622 | ōyashima,jp 623 | british east africa protectorate,ke 624 | jamhuri ya kenya,ke 625 | ke,ke 626 | ken,ke 627 | kenya,ke 628 | kenya colony,ke 629 | republic of kenya,ke 630 | kg,kg 631 | kgz,kg 632 | kirghiz soviet socialist republic,kg 633 | kirghizia,kg 634 | kirgizstan,kg 635 | kyrgyz republic,kg 636 | kyrgyzskaya respublika,kg 637 | kyrgyzstan,kg 638 | republic of kyrgyzstan,kg 639 | кыргызстан,kg 640 | cambodia,kh 641 | democratic kampuchea,kh 642 | kampuchea,kh 643 | kh,kh 644 | khm,kh 645 | khmer republic,kh 646 | kingdom of cambodia,kh 647 | people's republic of kampuchea,kh 648 | royaume du cambodge,kh 649 | state of cambodia,kh 650 | ki,ki 651 | kir,ki 652 | kiribati,ki 653 | al-ittiḥād al-qumurī,km 654 | com,km 655 | comoros,km 656 | km,km 657 | udzima wa komori,km 658 | union des comores,km 659 | union of the comoros,km 660 | united republic of the commoros,km 661 | federation of saint christopher and nevis,kn 662 | federation of saint kitts and nevis,kn 663 | kn,kn 664 | kna,kn 665 | liamuiga and oualie,kn 666 | saint christopher and nevis,kn 667 | saint christopher-nevis-anguilla,kn 668 | saint kitts and nevis,kn 669 | saint kitts-nevis-anguilla,kn 670 | cho-son,kp 671 | choson minjujuui inmin konghwaguk,kp 672 | d.p.r.k.,kp 673 | democratic people's republic of korea,kp 674 | dprk,kp 675 | kp,kp 676 | north korea,kp 677 | prk,kp 678 | dae-han-min-guk,kr 679 | han-guk,kr 680 | kor,kr 681 | korea,kr 682 | korea republic,kr 683 | kr,kr 684 | republic of korea,kr 685 | south korea,kr 686 | "korea, south",kr 687 | kuwait,kw 688 | kw,kw 689 | kwt,kw 690 | cayman islands,ky 691 | cym,ky 692 | ky,ky 693 | kaz,kz 694 | kazakh soviet socialist republic,kz 695 | kazakhstan,kz 696 | kz,kz 697 | qazaqstan,kz 698 | republic of kazakhstan,kz 699 | қазақстан,kz 700 | қазақстан республикасы,kz 701 | la,la 702 | lao,la 703 | lao people's democratic republic,la 704 | laos,la 705 | république démocratique populaire lao,la 706 | sathalanalat paxathipatai paxaxôn,la 707 | ສາທາລະນະລັດ ປະຊາທິປະໄຕ ປະຊາຊົນລາວ,la 708 | al-jumhuriyya al-lubnaniyya,lb 709 | lb,lb 710 | lbn,lb 711 | lebanon,lb 712 | lebnan,lb 713 | levanon,lb 714 | liban,lb 715 | lubnan,lb 716 | the lebanese republic,lb 717 | lc,lc 718 | lca,lc 719 | saint lucia,lc 720 | li,li 721 | lie,li 722 | liechtenstein,li 723 | ceylon,lk 724 | democratic socialist republic of sri lanka,lk 725 | heladiva,lk 726 | lk,lk 727 | lka,lk 728 | ratnadeepa,lk 729 | sri lanka,lk 730 | taprobane,lk 731 | lbr,lr 732 | liberia,lr 733 | lr,lr 734 | basutoland,ls 735 | kingdom of lesotho,ls 736 | lesotho,ls 737 | ls,ls 738 | lso,ls 739 | lietuva,lt 740 | lietuvos respublika,lt 741 | lita,lt 742 | lithuania,lt 743 | lt,lt 744 | ltu,lt 745 | литва,lt 746 | grand duchy of luxembourg,lu 747 | grand-duché de luxembourg,lu 748 | groussherzogdem lëtzebuerg,lu 749 | großherzogtum luxemburg,lu 750 | lu,lu 751 | lussemburgo,lu 752 | lux,lu 753 | luxembourg,lu 754 | luxemburg,lu 755 | luxemburgo,lu 756 | lëtzebuerg,lu 757 | latvia,lv 758 | latvija,lv 759 | letland,lv 760 | letonija,lv 761 | letonnie,lv 762 | lettland,lv 763 | lv,lv 764 | lva,lv 765 | lby,ly 766 | libya,ly 767 | ly,ly 768 | al mamkaka al maghribiya,ma 769 | kingdom of morocco,ma 770 | ma,ma 771 | mar,ma 772 | morocco,ma 773 | mc,mc 774 | mco,mc 775 | monaco,mc 776 | boğdan,md 777 | md,md 778 | mda,md 779 | moldau,md 780 | moldavia,md 781 | moldavian soviet socialist republic,md 782 | moldova,md 783 | republic of moldova,md 784 | republica moldova,md 785 | me,me 786 | mne,me 787 | montenegro,me 788 | republic of montenegro,me 789 | maf,mf 790 | mf,mf 791 | collectivity of saint martin,mf 792 | saint martin,mf 793 | madagascar,mg 794 | madagasikara,mg 795 | mdg,mg 796 | mg,mg 797 | repoblikan'i madagasikara,mg 798 | republic of madagascar,mg 799 | république de madagascar,mg 800 | mhl,mh 801 | mh,mh 802 | marshall islands,mh 803 | macedonia,mk 804 | mk,mk 805 | mkd,mk 806 | north macedonia,mk 807 | paeonia,mk 808 | republic of north macedonia,mk 809 | vardar banovina,mk 810 | македонија,mk 811 | северна македонија,mk 812 | mali,ml 813 | ml,ml 814 | mli,ml 815 | burma,mm 816 | mm,mm 817 | mmr,mm 818 | myanmar,mm 819 | republic of the union of myanmar,mm 820 | mng,mn 821 | mongolia,mn 822 | the state of mongolia,mn 823 | mac,mo 824 | macao,mo 825 | mo,mo 826 | mnp,mp 827 | mp,mp 828 | northern mariana islands,mp 829 | martinique,mq 830 | mq,mq 831 | mtq,mq 832 | islamic republic of mauritania,mr 833 | mauritania,mr 834 | mr,mr 835 | mrt,mr 836 | république islamique de mauritanie,mr 837 | montserrat,ms 838 | ms,ms 839 | msr,ms 840 | malta,mt 841 | mlt,mt 842 | mt,mt 843 | mauritius,mu 844 | mu,mu 845 | mus,mu 846 | maldives,mv 847 | mdv,mv 848 | mv,mv 849 | republic of the maldives,mv 850 | the maldive islands,mv 851 | malawi,mw 852 | mw,mw 853 | mwi,mw 854 | nyasaland,mw 855 | republic of malawi,mw 856 | aztlán,mx 857 | aztlān,mx 858 | estados unidos mexicanos,mx 859 | mex,mx 860 | mexico,mx 861 | mx,mx 862 | méjico,mx 863 | méxico,mx 864 | república mexicana,mx 865 | united mexican states,mx 866 | federation of malaysia,my 867 | malaysia,my 868 | my,my 869 | mys,my 870 | persekutuan malaysia,my 871 | moz,mz 872 | mozambique,mz 873 | mz,mz 874 | namibia,na 875 | na,na 876 | nam,na 877 | nc,nc 878 | ncl,nc 879 | new caledonia,nc 880 | ne,ne 881 | ner,ne 882 | niger,ne 883 | nf,nf 884 | nfk,nf 885 | norfolk island,nf 886 | ng,ng 887 | nga,ng 888 | nigeria,ng 889 | ni,ni 890 | nic,ni 891 | nicaragua,ni 892 | batavia,nl 893 | holland,nl 894 | kingdom of the netherlands,nl 895 | koninkrijk der nederlanden,nl 896 | nederland,nl 897 | netherlands,nl 898 | nl,nl 899 | nld,nl 900 | pays-bas,nl 901 | kingdom of norway,no 902 | kongeriket noreg,no 903 | kongeriket norge,no 904 | no,no 905 | nor,no 906 | noreg,no 907 | norge,no 908 | norway,no 909 | federal democratic republic of nepal,np 910 | nepal,np 911 | np,np 912 | npl,np 913 | nauru,nr 914 | nr,nr 915 | nru,nr 916 | niu,nu 917 | niue,nu 918 | nu,nu 919 | aotearoa,nz 920 | dominion of new zealand,nz 921 | new zealand,nz 922 | nz,nz 923 | nzl,nz 924 | realm of new zealand,nz 925 | om,om 926 | oman,om 927 | omn,om 928 | sultanate of oman,om 929 | pa,pa 930 | pan,pa 931 | panama,pa 932 | pe,pe 933 | per,pe 934 | peru,pe 935 | peruvian republic,pe 936 | perú,pe 937 | republic of peru,pe 938 | república del perú,pe 939 | república peruana,pe 940 | french polynesia,pf 941 | pf,pf 942 | pyf,pf 943 | papua new guinea,pg 944 | pg,pg 945 | png,pg 946 | filipina,ph 947 | filipinas,ph 948 | haríng bayang katagalugan,ph 949 | islas de san lázaro,ph 950 | las islas felipenas,ph 951 | las islas filipinas,ph 952 | ph,ph 953 | philippine islands,ph 954 | philippines,ph 955 | phl,ph 956 | pilipinas,ph 957 | pinás,ph 958 | republic of the philippines,ph 959 | repúblika ng pilipinas,ph 960 | dominion of pakistan,pk 961 | federation of pakistan,pk 962 | islamic republic of pakistan,pk 963 | mumlikat-e khudadaad pakistan,pk 964 | pak,pk 965 | pakistan,pk 966 | pk,pk 967 | sindhustan and indoscythia,pk 968 | west pakistan,pk 969 | lechia,pl 970 | people's republic of poland,pl 971 | pl,pl 972 | pol,pl 973 | poland,pl 974 | polish-lithuanian commonwealth,pl 975 | polonia,pl 976 | polska,pl 977 | republic of poland,pl 978 | spm,pm 979 | pm,pm 980 | saint pierre and miquelon,pm 981 | pcn,pn 982 | pn,pn 983 | pitcairn,pn 984 | "pitcairn, henderson, ducie and oeno islands",pn 985 | associated free state of puerto rico,pr 986 | commonwealth of puerto rico,pr 987 | estado libre asociado de puerto rico,pr 988 | porto rico,pr 989 | pr,pr 990 | pri,pr 991 | puerto rico,pr 992 | israeli-occupied territories,ps 993 | mandatory palestine,ps 994 | palestine,ps 995 | palestinian national authority,ps 996 | palestinian territories,ps 997 | ps,ps 998 | pse,ps 999 | state of palestine,ps 1000 | west bank and gaza strip,ps 1001 | west bank and gaza,ps 1002 | and galician-portuguese,pt 1003 | and pátria lusitana,pt 1004 | lusitania,pt 1005 | portugal,pt 1006 | portuguese republic,pt 1007 | prt,pt 1008 | pt,pt 1009 | belau,pw 1010 | palau,pw 1011 | plw,pw 1012 | pw,pw 1013 | republic of palau,pw 1014 | paraguay,py 1015 | pry,py 1016 | py,py 1017 | qa,qa 1018 | qat,qa 1019 | qatar,qa 1020 | reu,re 1021 | re,re 1022 | réunion,re 1023 | reunion,re 1024 | kingdom of romania,ro 1025 | regatul româniei,ro 1026 | republica populară romînă,ro 1027 | republica socialistă românia,ro 1028 | ro,ro 1029 | romania,ro 1030 | romanian people's republic,ro 1031 | românia,ro 1032 | rou,ro 1033 | socialist republic of romania,ro 1034 | raška,rs 1035 | republic of serbia,rs 1036 | republika srbija,rs 1037 | rs,rs 1038 | serbia,rs 1039 | serbia and montenegro,rs 1040 | serboslavia,rs 1041 | servia,rs 1042 | srb,rs 1043 | srbija,rs 1044 | yugoslavia,rs 1045 | ru,ru 1046 | rus,ru 1047 | russia,ru 1048 | russian federation,ru 1049 | russian socialist federative soviet republic,ru 1050 | russian soviet federative socialist republic,ru 1051 | soviet union,ru 1052 | union of soviet socialist republics,ru 1053 | ussr,ru 1054 | republic of rwanda,rw 1055 | repubulika y'u rwanda,rw 1056 | ruanda,rw 1057 | rw,rw 1058 | rwa,rw 1059 | rwanda,rw 1060 | rwandese republic,rw 1061 | république du rwanda,rw 1062 | kingdom of saudi arabia,sa 1063 | ksa,sa 1064 | sa,sa 1065 | sau,sa 1066 | saudi arabia,sa 1067 | saudia,sa 1068 | sb,sb 1069 | slb,sb 1070 | solomon islands,sb 1071 | sc,sc 1072 | seychelles,sc 1073 | syc,sc 1074 | anglo-egyptian sudan,sd 1075 | mahdist state,sd 1076 | nubia,sd 1077 | republic of the sudan,sd 1078 | sd,sd 1079 | sdn,sd 1080 | sudan,sd 1081 | the sudan,sd 1082 | kingdom of sweden,se 1083 | konungariket sverige,se 1084 | se,se 1085 | svea rike,se 1086 | sverige,se 1087 | svitjod,se 1088 | swe,se 1089 | sweden,se 1090 | pulau ujong,sg 1091 | republic of singapore,sg 1092 | sg,sg 1093 | sgp,sg 1094 | singapore,sg 1095 | singapura,sg 1096 | sinhapura,sg 1097 | shn,sh 1098 | sh,sh 1099 | saint helena,sh 1100 | "saint helena, ascension and tristan da cunha",sh 1101 | republic of slovenia,si 1102 | republika slovenija,si 1103 | si,si 1104 | slovenia,si 1105 | slovenija,si 1106 | svn,si 1107 | sjm,sj 1108 | sj,sj 1109 | svalbard and jan mayen,sj 1110 | sk,sk 1111 | slovak republic,sk 1112 | slovak socialist republic,sk 1113 | slovakia,sk 1114 | slovensko,sk 1115 | slovenská republika,sk 1116 | slovenská socialistická republika,sk 1117 | svk,sk 1118 | sierra leone,sl 1119 | sl,sl 1120 | sle,sl 1121 | san marino,sm 1122 | sm,sm 1123 | smr,sm 1124 | sen,sn 1125 | senegal,sn 1126 | sn,sn 1127 | so,so 1128 | som,so 1129 | somalia,so 1130 | dutch guiana,sr 1131 | netherlands guiana,sr 1132 | republic of suriname,sr 1133 | republiek suriname,sr 1134 | sr,sr 1135 | sur,sr 1136 | surinam,sr 1137 | suriname,sr 1138 | south sudan,ss 1139 | ss,ss 1140 | ssd,ss 1141 | sao tome and principe,st 1142 | st,st 1143 | stp,st 1144 | el salvador,sv 1145 | slv,sv 1146 | sv,sv 1147 | sxm,sx 1148 | sx,sx 1149 | sint maarten,sx 1150 | sy,sy 1151 | syr,sy 1152 | syria,sy 1153 | eswatini,sz 1154 | kingdom of eswatini,sz 1155 | swaziland,sz 1156 | swz,sz 1157 | sz,sz 1158 | tc,tc 1159 | tca,tc 1160 | turks and caicos,tc 1161 | chad,td 1162 | jumhūrīyat tashād,td 1163 | republic of chad,td 1164 | république du tchad,td 1165 | tcd,td 1166 | td,td 1167 | atf,tf 1168 | tf,tf 1169 | french southern territories,tf 1170 | french southern and antarctic lands,tf 1171 | tg,tg 1172 | tgo,tg 1173 | togo,tg 1174 | kingdom of thailand,th 1175 | siam,th 1176 | th,th 1177 | tha,th 1178 | thailand,th 1179 | ประเทศสยาม,th 1180 | ประเทศไทย,th 1181 | ราชอาณาจักรไทย,th 1182 | tajikistan,tj 1183 | tj,tj 1184 | tjk,tj 1185 | tk,tk 1186 | tkl,tk 1187 | tokelau,tk 1188 | democratic republic of timor-leste,tl 1189 | east timor,tl 1190 | timor-leste,tl 1191 | tl,tl 1192 | tls,tl 1193 | tkm,tm 1194 | tm,tm 1195 | turkmenistan,tm 1196 | republic of tunisia,tn 1197 | tn,tn 1198 | tun,tn 1199 | tunisia,tn 1200 | to,to 1201 | ton,to 1202 | tonga,to 1203 | anatolia,tr 1204 | ottoman empire,tr 1205 | republic of turkey,tr 1206 | tr,tr 1207 | tur,tr 1208 | turkey,tr 1209 | iere,tt 1210 | republic of trinidad and tobago,tt 1211 | trinbago,tt 1212 | trinidad and tobago,tt 1213 | tt,tt 1214 | tto,tt 1215 | ellice islands,tv 1216 | tuv,tv 1217 | tuvalu,tv 1218 | tv,tv 1219 | cathay,tw 1220 | formosa,tw 1221 | republic of china,tw 1222 | roc,tw 1223 | taiwan,tw 1224 | tw,tw 1225 | twn,tw 1226 | zhonggua taipei,tw 1227 | zhongguo,tw 1228 | tanzania,tz 1229 | tz,tz 1230 | tza,tz 1231 | united republic of tanganyika and zanzibar,tz 1232 | united republic of tanzania,tz 1233 | ua,ua 1234 | ukr,ua 1235 | ukraine,ua 1236 | україна,ua 1237 | ug,ug 1238 | uga,ug 1239 | uganda,ug 1240 | umi,um 1241 | um,um 1242 | united states minor outlying islands,um 1243 | u.s.a,us 1244 | united states,us 1245 | united states of america,us 1246 | us,us 1247 | usa,us 1248 | uruguay,uy 1249 | ury,uy 1250 | uy,uy 1251 | uz,uz 1252 | uzb,uz 1253 | uzbekistan,uz 1254 | va,va 1255 | vat,va 1256 | vatican city,va 1257 | holy see,va 1258 | the holy see,va 1259 | holy see (the),va 1260 | hairouna,vc 1261 | saint vincent and the grenadines,vc 1262 | vc,vc 1263 | vct,vc 1264 | ve,ve 1265 | ven,ve 1266 | venezuela,ve 1267 | vgb,vg 1268 | vg,vg 1269 | british virgin islands,vg 1270 | bvi,vg 1271 | virgin islands,vg 1272 | vir,vi 1273 | vi,vi 1274 | usvi,vi 1275 | united states virgin islands,vi 1276 | american virgin islands,vi 1277 | u.s. virgin islands,vi 1278 | virgin islands of the united states,vi 1279 | an nam,vn 1280 | and south vietnam,vn 1281 | champa,vn 1282 | french indochina,vn 1283 | giao chỉ,vn 1284 | lĩnh nam,vn 1285 | parted in north vietnam,vn 1286 | socialist republic of vietnam,vn 1287 | vietnam,vn 1288 | việt nam,vn 1289 | vn,vn 1290 | vnm,vn 1291 | đại việt,vn 1292 | vanuatri,vu 1293 | vanuatu,vu 1294 | vu,vu 1295 | vut,vu 1296 | wlf,wf 1297 | wf,wf 1298 | wallis and futuna,wf 1299 | territory of the wallis and futuna isla,wf 1300 | samoa,ws 1301 | ws,ws 1302 | wsm,ws 1303 | kosovo,xk 1304 | republic of kosovo,xk 1305 | republika e kosovës,xk 1306 | republika kosovo,xk 1307 | xk,xk 1308 | република косово,xk 1309 | ye,ye 1310 | yem,ye 1311 | yemen,ye 1312 | mayotte,yt 1313 | myt,yt 1314 | yt,yt 1315 | south africa,za 1316 | suid-afrika,za 1317 | union of south africa,za 1318 | za,za 1319 | zaf,za 1320 | zuid-afrika,za 1321 | northern rhodesia,zm 1322 | republic of zambia,zm 1323 | zambia,zm 1324 | zm,zm 1325 | zmb,zm 1326 | republic of zimbabwe,zw 1327 | southern rhodesia,zw 1328 | zimbabwe,zw 1329 | zw,zw 1330 | zwe,zw 1331 | -------------------------------------------------------------------------------- /bar_chart_race/_codes/nfl.csv: -------------------------------------------------------------------------------- 1 | code,value 2 | arizona cardinals,https://www.thesportsdb.com/images/media/team/badge/xvuwtw1420646838.png/preview 3 | atlanta falcons,https://www.thesportsdb.com/images/media/team/badge/rrpvpr1420658174.png/preview 4 | baltimore ravens,https://www.thesportsdb.com/images/media/team/badge/einz3p1546172463.png/preview 5 | buffalo bills,https://www.thesportsdb.com/images/media/team/badge/6pb37b1515849026.png/preview 6 | carolina panthers,https://www.thesportsdb.com/images/media/team/badge/xxyvvy1420940478.png/preview 7 | chicago bears,https://www.thesportsdb.com/images/media/team/badge/uwtwtv1420941123.png/preview 8 | cincinnati bengals,https://www.thesportsdb.com/images/media/team/badge/qqtwwv1420941670.png/preview 9 | cleveland browns,https://www.thesportsdb.com/images/media/team/badge/squvxy1420942389.png/preview 10 | dallas cowboys,https://www.thesportsdb.com/images/media/team/badge/wrxssu1450018209.png/preview 11 | denver broncos,https://www.thesportsdb.com/images/media/team/badge/upsspx1421635647.png/preview 12 | detroit lions,https://www.thesportsdb.com/images/media/team/badge/lgsgkr1546168257.png/preview 13 | green bay packers,https://www.thesportsdb.com/images/media/team/badge/rqpwtr1421434717.png/preview 14 | houston texans,https://www.thesportsdb.com/images/media/team/badge/wqyryy1421436627.png/preview 15 | indianapolis colts,https://www.thesportsdb.com/images/media/team/badge/wqqvpx1421434058.png/preview 16 | jacksonville jaguars,https://www.thesportsdb.com/images/media/team/badge/0mrsd41546427902.png/preview 17 | kansas city chiefs,https://www.thesportsdb.com/images/media/team/badge/936t161515847222.png/preview 18 | las vegas raiders,https://www.thesportsdb.com/images/media/team/badge/xqusqy1421724291.png/preview 19 | los angeles chargers,https://www.thesportsdb.com/images/media/team/badge/wbhu3a1548320628.png/preview 20 | los angeles rams,https://www.thesportsdb.com/images/media/team/badge/45ps1l1515847886.png/preview 21 | miami dolphins,https://www.thesportsdb.com/images/media/team/badge/trtusv1421435081.png/preview 22 | minnesota vikings,https://www.thesportsdb.com/images/media/team/badge/qstqqr1421609163.png/preview 23 | new england patriots,https://www.thesportsdb.com/images/media/team/badge/xtwxyt1421431860.png/preview 24 | new orleans saints,https://www.thesportsdb.com/images/media/team/badge/nd46c71537821337.png/preview 25 | new york giants,https://www.thesportsdb.com/images/media/team/badge/vxppup1423669459.png/preview 26 | new york jets,https://www.thesportsdb.com/images/media/team/badge/rurvuu1421435228.png/preview 27 | philadelphia eagles,https://www.thesportsdb.com/images/media/team/badge/pnpybf1515852421.png/preview 28 | pittsburgh steelers,https://www.thesportsdb.com/images/media/team/badge/2975411515853129.png/preview 29 | san francisco 49ers,https://www.thesportsdb.com/images/media/team/badge/bqbtg61539537328.png/preview 30 | seattle seahawks,https://www.thesportsdb.com/images/media/team/badge/wwuqyr1421434817.png/preview 31 | tampa bay buccaneers,https://www.thesportsdb.com/images/media/team/badge/2dfpdl1537820969.png/preview 32 | tennessee titans,https://www.thesportsdb.com/images/media/team/badge/m48yia1515847376.png/preview 33 | washington redskins,https://www.thesportsdb.com/images/media/team/badge/qsxwrv1425081054.png/preview 34 | -------------------------------------------------------------------------------- /bar_chart_race/_common_chart.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | from matplotlib import ticker 3 | 4 | 5 | class CommonChart: 6 | 7 | def get_extension(self): 8 | if self.filename: 9 | return self.filename.split('.')[-1] 10 | 11 | def get_title(self, title): 12 | if isinstance(title, str): 13 | return {'label': title} 14 | elif isinstance(title, dict): 15 | if 'label' not in title: 16 | raise ValueError('You must use the key "label" in the `title` dictionary ' 17 | 'to supply the name of the title') 18 | elif title is not None: 19 | raise TypeError('`title` must be either a string or dictionary') 20 | else: 21 | return {'label': None} 22 | return title 23 | 24 | def get_tick_template(self, tick_template): 25 | if isinstance(tick_template, str): 26 | return ticker.StrMethodFormatter(tick_template) 27 | elif callable(tick_template): 28 | return ticker.FuncFormatter(tick_template) 29 | 30 | def set_shared_fontdict(self, shared_fontdict): 31 | orig_rcParams = plt.rcParams.copy() 32 | if shared_fontdict is None: 33 | return orig_rcParams 34 | for k, v in shared_fontdict.items(): 35 | if k not in ['fontsize', 'size']: 36 | if k in ['cursive', 'family', 'fantasy', 'monospace', 'sans-serif', 'serif']: 37 | if isinstance(v, str): 38 | v = [v] 39 | if k == 'color': 40 | plt.rcParams['text.color'] = v 41 | plt.rcParams['xtick.color'] = v 42 | plt.rcParams['ytick.color'] = v 43 | continue 44 | try: 45 | plt.rcParams[f'font.{k}'] = v 46 | except KeyError: 47 | raise KeyError(f"{k} is not a valid key in `sharedfont_dict`" 48 | "It must be one of " 49 | "'cursive', 'family', 'fantasy', 'monospace', 'sans-serif'," 50 | "'serif', 'stretch','style', 'variant', 'weight'") 51 | return orig_rcParams 52 | 53 | def get_writer(self, writer): 54 | if writer is None: 55 | if self.extension == 'gif': 56 | writer = 'imagemagick' 57 | elif self.extension == 'html': 58 | writer = 'html' 59 | else: 60 | writer = plt.rcParams['animation.writer'] 61 | return writer 62 | 63 | def get_fig_kwargs(self, fig_kwargs): 64 | default_fig_kwargs = {'figsize': (6, 3.5), 'dpi': 144} 65 | if fig_kwargs is None: 66 | return default_fig_kwargs 67 | if isinstance(fig_kwargs, dict): 68 | fig_kwargs = {**default_fig_kwargs, **fig_kwargs} 69 | else: 70 | raise TypeError('fig_kwargs must be a dict or None') 71 | return fig_kwargs 72 | 73 | def get_fig(self, fig): 74 | if fig is not None and not isinstance(fig, plt.Figure): 75 | raise TypeError('`fig` must be a matplotlib Figure instance') 76 | if fig is not None: 77 | if not fig.axes: 78 | raise ValueError('The figure passed to `fig` must have an axes') 79 | ax = fig.axes[0] 80 | else: 81 | fig = self.create_figure() 82 | return fig 83 | -------------------------------------------------------------------------------- /bar_chart_race/_func_animation.py: -------------------------------------------------------------------------------- 1 | import base64 2 | from io import BytesIO, TextIOWrapper 3 | from pathlib import Path 4 | from tempfile import TemporaryDirectory 5 | 6 | from matplotlib import rcParams 7 | from matplotlib import animation 8 | 9 | class FuncAnimation(animation.FuncAnimation): 10 | 11 | def to_html5_video(self, embed_limit=None, savefig_kwargs=None): 12 | """ 13 | Convert the animation to an HTML5 ``