No topics yet. Start the conversation.

Description

The below description is supplied in free-text by the user

Verified losses by oryx

This table provides an aggregate view of the latest verified losses in the Ruso-Ukranian conflict.

Data is from the open source intelligence organisation Oryx as scraped daily by Lee Drake.

Information is updated every day and this plot is a part of the daily summary e-mail produced by novem reserach.

import pandas as pd
from novem import Plot

# Background:
# ldloss is a dataframe of 5 columns:
# country, equipment_type, cat, date, values
#
# * country - either russia or ukraine
# * date - the date the verified loss was first reported on oryx
# * cat - the type of loss, abandoned, destroyed etc
# * equipment_type - the super category of equipment, Tank, Artillery etc
# * values - the number of lost equipment of that type for that day for that 
#            country

md = ldloss.date.max()
std = pd.to_datetime(md)

ldl = pd.pivot_table(
    ldloss.loc[ldloss.date == ldloss.date.max()], 
    index='equipment_type', 
    columns=['country','cat'], 
    values='values', 
    aggfunc='sum'
)

ldl = ldl.sort_values(by=('Russia','tot'), ascending=False)
ldl = ldl.applymap(lambda x: np.nan if x==0 else x)

# we don't want category values in our visual
ldl.columns = ldl.columns.set_names(['',''])
ldl.index.name = ''

# drop rows where all values are missing
ldl = ldl.dropna(axis=0, how='all')

caption = f"""Breakdown by country, equipment type and state.

Verified losses by Oryx as of {md}, raw data by 
[Oryx](https://www.oryxspioenkop.com/2022/02/attack-on-europe-documenting-equipment.html),
scraped by [Lee Drake](https://github.com/leedrake5), standardization, 
calculations and presentations by Novem.
"""

# let's construct loss list
lt = Plot('ruc_loss_bt_oryx_pvt',
    name=f'Verified losses on {std:%B %-d %Y}',
    caption=caption,
    type='logo'
    )

# Add top border and country divider
lt.cell.border = """
1 : b 1 inverse
1: 6 l 1 inverse
"""

# Merge first header row column 1-5 for russia
lt.cell.merge = '0 1:5 ru'

# Merge first header row column 6 to end of row for ukraine
lt.cell.merge += '0 6: ukr'

# Bold first two columns
lt.cell.text = ':1 : b'

# Center text in first two columns
# use += to take advantage of default values
lt.cell.align += ':1 1: -'

# format loss data, integer so no decimal marks
lt.cell.format += '2: 1: ,.0f' 

# Add some spacing
lt.cell.padding = """
2: : x 2
"""

# create our color category and banding effect
lt.colors = """
2: 1,6 bg gray-100
2: 2,7 bg green-100
2: 3,8 bg orange-100
2: 4,9 bg red-100
2: 5,10 bg gray-100

2::2 1,6 bg gray-200
2::2 2,7 bg green-200
2::2 3,8 bg orange-200
2::2 4,9 bg red-200
2::2 5,10 bg gray-200
"""
lt.colors.type = 'ix'

# set our data, an alternative to ldl.pipe(lt)
lt.data = ldl

lt.shared = 'public'

lt.type = 'mtable'