Skip to content

Commit

Permalink
switch to subplots
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelsoup42 committed Oct 13, 2023
1 parent fde3074 commit e483c43
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 137 deletions.
8 changes: 1 addition & 7 deletions src/cardano_account_pandas_dumper/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,6 @@ def _create_arg_parser():
type=str,
default=os.path.join(os.path.dirname(os.path.abspath(__file__)), "matplotlib.rc"),
)
result.add_argument(
"--log_scale",
help="Use log scale on graph, default=automatic.",
type=bool,
default=None,
)
result.add_argument(
"--detail_level",
help="Level of detail of report (1=only own addresses, 2=other addresses as well).",
Expand Down Expand Up @@ -244,7 +238,7 @@ def main():
if args.graph_output:
with mpl.rc_context(fname=args.matplotlib_rc):
try:
reporter.plot_balance(log_scale=args.log_scale)
reporter.plot_balance()
plt.savefig(args.graph_output,
metadata=reporter.get_graph_metadata(args.graph_output))
except OSError as exception:
Expand Down
135 changes: 8 additions & 127 deletions src/cardano_account_pandas_dumper/cardano_account_pandas_dumper.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,20 @@
""" Cardano Account To Pandas Dumper."""
import datetime
import itertools
from base64 import b64decode
from collections import defaultdict
from io import BytesIO
import os
from typing import (
Any,
Callable,
Dict,
FrozenSet,
List,
Mapping,
MutableMapping,
Optional,
Set,
Tuple,
cast,
)
from collections import defaultdict
from typing import (Any, Callable, Dict, FrozenSet, List, Mapping,
MutableMapping, Optional, Set, Tuple, cast)

import blockfrost.utils
import matplotlib as mpl
import matplotlib.pyplot as pyplot

from matplotlib.font_manager import FontProperties
from matplotlib.image import BboxImage
from matplotlib.legend_handler import HandlerBase
from matplotlib.patches import Rectangle
from matplotlib.transforms import TransformedBbox
from matplotlib import pyplot
import numpy as np
import pandas as pd
from blockfrost import BlockFrostApi




class AccountData:
"""Hold data retrieved from the API to allow checkpointing it."""

Expand Down Expand Up @@ -166,8 +146,6 @@ class AccountPandasDumper:

# Constants for graph output
CREATOR_STRING="https://github.com/pixelsoup42/cardano_account_pandas_dumper"
# Switch to log scale if difference between min and max is more than this order of magnitude
AUTO_LOG_SCALE_THRESHOLD=8

def __init__(
self,
Expand Down Expand Up @@ -612,113 +590,16 @@ def make_transaction_frame(
joined_frame = pd.concat(objs=[msg_frame, balance_frame], axis=1)
return joined_frame

class _ImageLegendHandler(HandlerBase):
def __init__(self, color, asset_id: str,
asset_obj: Optional[blockfrost.utils.Namespace]) -> None:
self.asset_id=asset_id
self.asset_obj=asset_obj
self.color=color
super().__init__()

def create_artists(
self,
legend,
orig_handle,
xdescent,
ydescent,
width,
height,
fontsize,
trans,
):
rectangle = Rectangle(xy=(xdescent, ydescent),
width=width, height=height, color=self.color)
if self.asset_id == AccountPandasDumper.ADA_ASSET:
image_data=os.path.join(os.path.dirname(os.path.abspath(__file__)), "ada_logo.webp")
elif (self.asset_obj is not None
and hasattr(self.asset_obj , "metadata")
and hasattr(self.asset_obj.metadata, "logo")
and self.asset_obj.metadata.logo):
image_data= BytesIO(b64decode(self.asset_obj.metadata.logo))
else:
image_data = None
if image_data is not None:
image = BboxImage(
TransformedBbox(
rectangle.get_bbox().expanded(0.7, 0.7), transform=trans
),
)
image.set_data(mpl.image.imread(image_data))

self.update_prop(image, orig_handle, legend)

return [rectangle, image]
else:
return [rectangle]

def _plot_title(self):
return f"Asset balances in wallet until block {self.data.to_block}."

def _auto_log_scale(self,balance : pd.DataFrame) -> bool:
# Ignore values that are lower than asset precision or NA when calculating min
min_mask = pd.concat(
[
balance[c]
.abs()
.ge(
np.float_power(
10,
np.negative(self.asset_decimals[c]),
)
)
for c in balance.columns
],
axis=1,
) & balance.notna()

balance_min=balance.where(min_mask,np.infty).abs().min(skipna=True,numeric_only=True).min()
balance_max=balance.abs().max(skipna=True,numeric_only=True).max()
return bool((np.log10(balance_max) - np.log10(balance_min)) > self.AUTO_LOG_SCALE_THRESHOLD)

def plot_balance(self, log_scale: Optional[bool]):
def plot_balance(self):
""" Create a Matplotlib plot with the asset balance over time."""
balance = self.make_balance_frame(with_total=False, raw_values=True).cumsum()
balance.sort_index(
axis=1,
level=0,
sort_remaining=True,
inplace=True,
key=lambda i: [self.asset_names.get(x, x) for x in i],
)
font_properties = FontProperties(size=mpl.rcParams['legend.fontsize'])
plot_ax=pyplot.subplot2grid(shape=(1,7),loc=(0,0),colspan=6)
legend_ax=pyplot.subplot2grid(shape=(1,7),loc=(0,6),colspan=1)

plot=balance.plot(
ax=plot_ax,
logy=log_scale if log_scale is not None else self._auto_log_scale(balance),
balance = self.make_balance_frame(with_total=False,raw_values=False).cumsum()
balance.plot(
title=self._plot_title(),
legend=False,
subplots=True
)
# Get font size
text=pyplot.text(x=0,y=0,s="M", font_properties=font_properties)
text_bbox=text.get_window_extent()
text.remove()
legend_ax.axis("off")
for text in legend_ax.legend(
plot.get_lines(),
cast(List[str],[self.asset_names.get(c, c) for c in balance.columns]),
handler_map={
plot.get_lines()[i]:
self._ImageLegendHandler(color=f"C{i}",
asset_id=balance.columns[i],
asset_obj=self.data.assets.get(balance.columns[i],None))
for i in range(len(balance.columns))
},

).get_texts():
text.set(y=text.get_window_extent().y0 +
mpl.rcParams['legend.handleheight'] * text_bbox.height / 2)

def get_graph_metadata(self, filename:str) -> Mapping :
"""Return graph metadata depending on file extension."""
Expand Down
6 changes: 3 additions & 3 deletions src/cardano_account_pandas_dumper/matplotlib.rc
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ axes.formatter.limits: -10, 12
axes.grid: True
axes.grid.which: both
axes.titleweight: bold
figure.autolayout: True
figure.figsize: 20,14
figure.constrained_layout.use: True
figure.figsize: 20,40
legend.fontsize:medium
legend.frameon:False
legend.handleheight:2
legend.handlelength:2
legend.labelcolor:linecolor
legend.loc:center
legend.loc:upper left
savefig.pad_inches:0.5

0 comments on commit e483c43

Please sign in to comment.