fixed saving png issue

This commit is contained in:
2026-01-29 10:43:05 +01:00
parent 0485f991d2
commit 36d8bc4d88

View File

@@ -8,6 +8,7 @@ import pandas as pd
import polars as pl
from theme import ColorPalette
import hashlib
class JPMCPlotsMixin:
"""Mixin class for plotting functions in JPMCSurvey."""
@@ -56,8 +57,13 @@ class JPMCPlotsMixin:
continue
if len(value) > 3:
# If more than 3 options selected, use count to keep slug short
val_str = f"{len(value)}_grps"
# If more than 3 options selected, create a hash of the sorted values
# This ensures uniqueness properly while keeping the slug short
sorted_vals = sorted([str(v) for v in value])
vals_str = "".join(sorted_vals)
# Create short 6-char hash
val_hash = hashlib.md5(vals_str.encode()).hexdigest()[:6]
val_str = f"{len(value)}_grps_{val_hash}"
else:
# Join values with '+'
clean_values = []
@@ -196,9 +202,25 @@ class JPMCPlotsMixin:
path.mkdir(parents=True, exist_ok=True)
filename = f"{self._sanitize_filename(title)}.png"
filepath = path / filename
# Save using vl-convert backend
chart.save(str(path / filename), format='png', scale_factor=2.0)
# Use vl_convert directly with theme config for consistent rendering
import vl_convert as vlc
from theme import jpmc_altair_theme
# Get chart spec and theme config
chart_spec = chart.to_dict()
theme_config = jpmc_altair_theme()['config']
png_data = vlc.vegalite_to_png(
vl_spec=chart_spec,
scale=2.0,
ppi=72,
config=theme_config
)
with open(filepath, 'wb') as f:
f.write(png_data)
return chart
@@ -282,7 +304,7 @@ class JPMCPlotsMixin:
# Combine layers
chart = (bars + text).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
)
@@ -339,7 +361,7 @@ class JPMCPlotsMixin:
]
).add_params(selection).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
)
@@ -399,7 +421,7 @@ class JPMCPlotsMixin:
]
).add_params(selection).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
)
@@ -452,7 +474,7 @@ class JPMCPlotsMixin:
]
).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
)
@@ -493,7 +515,7 @@ class JPMCPlotsMixin:
chart = (bars + text).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
)
@@ -550,7 +572,7 @@ class JPMCPlotsMixin:
]
).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
)
@@ -606,7 +628,7 @@ class JPMCPlotsMixin:
]
).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
)
@@ -663,9 +685,10 @@ class JPMCPlotsMixin:
else:
trait_description = ""
# Horizontal bar chart
# Horizontal bar chart - use x2 to explicitly start bars at x=1
bars = alt.Chart(stats).mark_bar(color=ColorPalette.PRIMARY).encode(
x=alt.X('mean_score:Q', title='Average Score (1-5)', scale=alt.Scale(domain=[1, 5])),
x2=alt.datum(1), # Bars start at x=1 (left edge of domain)
y=alt.Y('Voice:N', title='Voice', sort='-x'),
tooltip=[
alt.Tooltip('Voice:N'),
@@ -674,24 +697,29 @@ class JPMCPlotsMixin:
]
)
# Count text inside bars
text = bars.mark_text(
align='center',
# Count text at end of bars (right-aligned inside bar)
text = alt.Chart(stats).mark_text(
align='right',
baseline='middle',
color='white',
fontSize=16
fontSize=12,
dx=-5 # Slight padding from bar end
).encode(
x='mean_score:Q',
y=alt.Y('Voice:N', sort='-x'),
text='count:Q'
)
# Combine
# Combine layers
chart = (bars + text).properties(
title={
"text": title,
"subtitle": [trait_description, "(Numbers on bars indicate respondent count)"]
},
width=width if width else 'container',
width=width or 800,
height=height or getattr(self, 'plot_height', 400)
).configure_view(
strokeWidth=0 # Remove frame which might obscure labels
)
chart = self._save_plot(chart, title)
@@ -749,7 +777,7 @@ class JPMCPlotsMixin:
]
).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or 350
)
@@ -805,7 +833,7 @@ class JPMCPlotsMixin:
]
).properties(
title=title,
width=width if width else 'container',
width=width or 800,
height=height or 350
)