Skip to content

Commit

Permalink
Add lux.config.plotting_scale factor (#333)
Browse files Browse the repository at this point in the history
* Use altair/Choropleth.py in MatpltlibRenderer.py to render choropleths; include warning

* Add ._chart_scale to lux.config, accessible for AltairChart

* Sync with previous upstream

* Update fcode in frame

* Support positive ints or floats

* Change from chart_scale to plotting_scale

* Apply plotting_scale to matplotlib

* Black reformat

* Revert matplotlib change => yields clearer output

* Clean up diff

* Config traitlet

* black

Co-authored-by: dorisjlee <dorisjunglinlee@gmail.com>
  • Loading branch information
micahtyong and dorisjlee committed May 21, 2021
1 parent 2db6964 commit 6c98f43
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 17 deletions.
21 changes: 21 additions & 0 deletions lux/_config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(self):
self.update_actions: Dict[str, bool] = {}
self.update_actions["flag"] = False
self._plotting_backend = "vegalite"
self._plotting_scale = 1
self._topk = 15
self._sort = "descending"
self._pandas_fallback = True
Expand Down Expand Up @@ -295,6 +296,26 @@ def plotting_backend(self, type: str) -> None:
stacklevel=2,
)

@property
def plotting_scale(self):
return self._plotting_scale

@plotting_scale.setter
def plotting_scale(self, scale: float) -> None:
"""
Set the scale factor for charts displayed in Lux.
----------
type : float (default = 1.0)
"""
scale = float(scale) if isinstance(scale, int) else scale
if isinstance(scale, float) and scale > 0:
self._plotting_scale = scale
else:
warnings.warn(
"Scaling factor for charts must be a positive float.",
stacklevel=2,
)

def _get_action(self, pat: str, silent: bool = False):
return lux.actions[pat]

Expand Down
1 change: 1 addition & 0 deletions lux/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ def render_widget(self, renderer: str = "altair", input_current_vis=""):
recommendations=widgetJSON["recommendation"],
intent=LuxDataFrame.intent_to_string(self._intent),
message=self._message.to_html(),
config={"plottingScale": lux.config.plotting_scale},
)

@staticmethod
Expand Down
1 change: 1 addition & 0 deletions lux/vis/Vis.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def _ipython_display_(self):
recommendations=[],
intent="",
message="",
config={"plottingScale": lux.config.plotting_scale},
)
display(widget)

Expand Down
8 changes: 7 additions & 1 deletion lux/vis/VisList.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,13 @@ def _ipython_display_(self):
import luxwidget

recJSON = LuxDataFrame.rec_to_JSON([recommendation])
self._widget = luxwidget.LuxWidget(currentVis={}, recommendations=recJSON, intent="", message="")
self._widget = luxwidget.LuxWidget(
currentVis={},
recommendations=recJSON,
intent="",
message="",
config={"plottingScale": lux.config.plotting_scale},
)
display(self._widget)

def refresh_source(self, ldf):
Expand Down
8 changes: 6 additions & 2 deletions lux/vislib/altair/AltairChart.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import numpy as np
import altair as alt
from lux.utils.date_utils import compute_date_granularity
import lux


class AltairChart:
Expand Down Expand Up @@ -69,15 +70,18 @@ def apply_default_config(self):
labelFontSize=9,
labelFont="Helvetica Neue",
)
self.chart = self.chart.properties(width=160, height=150)
plotting_scale = lux.config.plotting_scale
self.chart = self.chart.properties(width=160 * plotting_scale, height=150 * plotting_scale)
self.code += (
"\nchart = chart.configure_title(fontWeight=500,fontSize=13,font='Helvetica Neue')\n"
)
self.code += "chart = chart.configure_axis(titleFontWeight=500,titleFontSize=11,titleFont='Helvetica Neue',\n"
self.code += "\t\t\t\t\tlabelFontWeight=400,labelFontSize=8,labelFont='Helvetica Neue',labelColor='#505050')\n"
self.code += "chart = chart.configure_legend(titleFontWeight=500,titleFontSize=10,titleFont='Helvetica Neue',\n"
self.code += "\t\t\t\t\tlabelFontWeight=400,labelFontSize=8,labelFont='Helvetica Neue')\n"
self.code += "chart = chart.properties(width=160,height=150)\n"
self.code += (
f"chart = chart.properties(width={160 * plotting_scale},height={150 * plotting_scale})\n"
)

def encode_color(self):
color_attr = self.vis.get_attr_by_channel("color")
Expand Down
10 changes: 6 additions & 4 deletions lux/vislib/altair/BarChart.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from lux.vislib.altair.AltairChart import AltairChart
import altair as alt
import lux

alt.data_transformers.disable_max_rows()
from lux.utils.utils import get_agg_title
Expand Down Expand Up @@ -101,23 +102,24 @@ def initialize_chart(self):
k = 10
self._topkcode = ""
n_bars = len(self.data.iloc[:, 0].unique())
plotting_scale = lux.config.plotting_scale

if n_bars > k: # Truncating to only top k
remaining_bars = n_bars - k
self.data = self.data.nlargest(k, columns=measure_attr)
self.data = AltairChart.sanitize_dataframe(self.data)
self.text = alt.Chart(self.data).mark_text(
x=155,
y=142,
x=155 * plotting_scale,
y=142 * plotting_scale,
align="right",
color="#ff8e04",
fontSize=11,
text=f"+ {remaining_bars} more ...",
)

self._topkcode = f"""text = alt.Chart(visData).mark_text(
x=155,
y=142,
x={155 * plotting_scale},
y={142 * plotting_scale},
align="right",
color = "#ff8e04",
fontSize = 11,
Expand Down
12 changes: 2 additions & 10 deletions lux/vislib/altair/Choropleth.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ def initialize_chart(self):
y_attr.attribute = y_attr.attribute.replace(".", "")

self.data = AltairChart.sanitize_dataframe(self.data)
height = 175
width = int(height * (5 / 3))

points = (
alt.Chart(geo_map)
Expand All @@ -76,9 +74,7 @@ def initialize_chart(self):
from_=alt.LookupData(self.data, str(x_attr.attribute), [str(y_attr.attribute)]),
)
.project(type=map_type)
.properties(
width=width, height=height, title=f"Mean of {y_attr_abv} across {geographical_name}"
)
.properties(title=f"Mean of {y_attr_abv} across {geographical_name}")
)

chart = background + points
Expand All @@ -101,8 +97,6 @@ def initialize_chart(self):
).project(
type="{map_type}"
).properties(
width={width},
height={height},
title="Mean of {y_attr_abv} across {geographical_name}"
)
chart = background + points
Expand All @@ -124,14 +118,12 @@ def get_background(self, feature):
),
}
assert feature in maps
height = 175
background = (
alt.Chart(maps[feature][0])
.mark_geoshape(fill="lightgray", stroke="white")
.properties(width=int(height * (5 / 3)), height=height)
.project(maps[feature][1])
)
background_str = f"(alt.Chart({maps[feature][2]}).mark_geoshape(fill='lightgray', stroke='white').properties(width=int({height} * (5 / 3)), height={height}).project('{maps[feature][1]}'))"
background_str = f"(alt.Chart({maps[feature][2]}).mark_geoshape(fill='lightgray', stroke='white').project('{maps[feature][1]}'))"
return background, background_str

def get_geomap(self, feature):
Expand Down

0 comments on commit 6c98f43

Please sign in to comment.