Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix png sizing #172

Merged
merged 10 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.8'
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
max-parallel: 5
matrix:
python-version: ["3.8", "3.9", "3.10"]
python-version: ["3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v3
Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ Ready to contribute? Here's how to set up `chartify` for local development.

Now you can make your changes locally.

5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox::
5. When you're done making changes, format using make black, check that your changes pass flake8 and the tests, including testing other Python versions with tox::

$ make black
$ flake8 chartify tests
$ python setup.py test or py.test
$ tox
Expand All @@ -106,7 +107,7 @@ Before you submit a pull request, check that it meets these guidelines:
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.rst.
3. The pull request should work for Python 3.8, 3.9 and 3.10. Check
3. The pull request should work for Python 3.9, 3.10 and 3.11. Check
https://github.com/spotify/chartify/actions
and make sure that the tests pass for all supported Python versions.

Expand Down
7 changes: 7 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
=======
History
=======
5.0.0 (2024-10-16)

* Drop support for Python 3.8
* Add support for Python 3.11
* Fixes bad cropping in png introduced by changes to chrome webdriver
* Add support and recommendation to use make black for code formatting

4.0.5 (2023-10-12)
------------------

Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,7 @@ release-prod: clean ## package and upload a release
twine upload dist/*

install-from-test-pypi:
pip3 install --index-url https://test.pypi.org/simple/ chartify
pip3 install --index-url https://test.pypi.org/simple/ chartify

black:
black chartify tests --line-length 119
6 changes: 4 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ Chartify
|status| |release| |python| |CI|

.. |status| image:: https://img.shields.io/badge/Status-Beta-blue.svg
.. |release| image:: https://img.shields.io/badge/Release-4.0.3-blue.svg
.. |python| image:: https://img.shields.io/badge/Python-3.7-blue.svg
.. |release| image:: https://img.shields.io/badge/Release-5.0.0-blue.svg
.. |python| image:: https://img.shields.io/badge/Python-3.9-blue.svg
.. |python| image:: https://img.shields.io/badge/Python-3.10-blue.svg
.. |python| image:: https://img.shields.io/badge/Python-3.11-blue.svg
.. |CI| image:: https://github.com/spotify/chartify/workflows/Tox/badge.svg
:target: https://github.com/spotify/chartify/actions

Expand Down
15 changes: 7 additions & 8 deletions chartify/_core/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
from collections import OrderedDict
from functools import wraps
import io
from io import BytesIO
import tempfile
import warnings

import bokeh
from bokeh.io.export import _SVG_SCRIPT, wait_until_render_complete
from bokeh.io.export import _SVG_SCRIPT, wait_until_render_complete, get_screenshot_as_png
import bokeh.plotting
from bokeh.embed import file_html

Expand Down Expand Up @@ -444,7 +443,7 @@ def _initialize_webdriver(self):
driver = webdriver.Chrome(options=options)
return driver

def _figure_to_png(self):
def _figure_to_png(self, force_resize=True, scale_factor=1):
"""Convert figure object to PNG
Bokeh can only save figure objects as html.
To convert to PNG the HTML file is opened in a headless browser.
Expand All @@ -458,14 +457,14 @@ def _figure_to_png(self):
# Open html file in the browser.
driver.get("file:///" + fp.name)
driver.execute_script("document.body.style.margin = '0px';")
png = driver.get_screenshot_as_png()
image = get_screenshot_as_png(self.figure, driver=driver, scale_factor=scale_factor)
driver.quit()
fp.close()
# Resize image if necessary.
image = Image.open(BytesIO(png))
target_dimensions = (self.style.plot_width, self.style.plot_height)
if image.size != target_dimensions:
image = image.resize(target_dimensions, resample=Resampling.LANCZOS)
if force_resize:
target_dimensions = (self.style.plot_width, self.style.plot_height)
if image.size != target_dimensions:
image = image.resize(target_dimensions, resample=Resampling.LANCZOS)
return image

def _set_svg_backend_decorator(f):
Expand Down
19 changes: 6 additions & 13 deletions chartify/_core/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,9 @@ def line(
else:
sliced_data = data_frame[data_frame[color_column] == color_value]
# Filter to only relevant columns.
sliced_data = sliced_data[[col for col in sliced_data.columns if col in (x_column, y_column, color_column)]]
sliced_data = sliced_data[
[col for col in sliced_data.columns if col in (x_column, y_column, color_column)]
]

cast_data = self._cast_datetime_axis(sliced_data, x_column)

Expand Down Expand Up @@ -959,29 +961,20 @@ def _sort_categories_by_value(source, categorical_columns, categorical_order_asc

hierarchical_sort_cols = categorical_columns[:]
for i, _ in enumerate(hierarchical_sort_cols):
row_totals["level_%s" % i] = row_totals.groupby(hierarchical_sort_cols[: i + 1])["_sum"].transform(
"sum"
)
row_totals["level_%s" % i] = row_totals.groupby(hierarchical_sort_cols[: i + 1])["_sum"].transform("sum")
row_totals = row_totals.sort_values(
by=["level_%s" % i for i, _ in enumerate(hierarchical_sort_cols)],
ascending=categorical_order_ascending,
)
return source.reindex(row_totals.index)

@staticmethod
def _sort_categories(
source,
categorical_columns,
categorical_order_by,
categorical_order_ascending
):

def _sort_categories(source, categorical_columns, categorical_order_by, categorical_order_ascending):
is_string = isinstance(categorical_order_by, str)
order_length = getattr(categorical_order_by, "__len__", None)
# Sort the categories
if is_string and categorical_order_by == "values":
return PlotMixedTypeXY._sort_categories_by_value(
source, categorical_columns, categorical_order_ascending)
return PlotMixedTypeXY._sort_categories_by_value(source, categorical_columns, categorical_order_ascending)
elif is_string and categorical_order_by == "labels":
return source.sort_index(axis=0, ascending=categorical_order_ascending)
# Manual sort
Expand Down
16 changes: 12 additions & 4 deletions chartify/_core/radar_chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ def text(

coord_df = sliced_data.copy()
coord_df[self._THETA_COLUMN] = self._get_thetas(len(coord_df))
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(coord_df, radius_column, self._THETA_COLUMN)
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(
coord_df, radius_column, self._THETA_COLUMN
)

source = self._named_column_data_source(coord_df, series_name=color_value)

Expand Down Expand Up @@ -214,7 +216,9 @@ def perimeter(

coord_df = sliced_data[[radius_column]].copy()
coord_df[self._THETA_COLUMN] = self._get_thetas(len(coord_df))
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(coord_df, radius_column, self._THETA_COLUMN)
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(
coord_df, radius_column, self._THETA_COLUMN
)
# Add endpoint
coord_df = pd.concat([coord_df, pd.DataFrame([coord_df.iloc[0]])])

Expand Down Expand Up @@ -267,7 +271,9 @@ def area(self, data_frame, radius_column, color_column=None, color_order=None, a

coord_df = sliced_data[[radius_column]].copy()
coord_df[self._THETA_COLUMN] = self._get_thetas(len(coord_df))
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(coord_df, radius_column, self._THETA_COLUMN)
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(
coord_df, radius_column, self._THETA_COLUMN
)
# Add endpoint
coord_df = pd.concat([coord_df, pd.DataFrame([coord_df.iloc[0]])])

Expand Down Expand Up @@ -337,7 +343,9 @@ def radius(

coord_df = sliced_data[[radius_column]].copy()
coord_df[self._THETA_COLUMN] = self._get_thetas(len(coord_df))
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(coord_df, radius_column, self._THETA_COLUMN)
coord_df[[self._X_COLUMN, self._Y_COLUMN]] = self._to_xy_coords(
coord_df, radius_column, self._THETA_COLUMN
)

color_value = str(color_value) if color_value is not None else color_value

Expand Down
4 changes: 2 additions & 2 deletions chartify/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ def style_color_palette_sequential():
id_vars=["time"],
value_vars=data.columns[1:],
value_name="y",
var_name=["grouping"],
var_name="grouping",
)

# Plot the data
Expand Down Expand Up @@ -1306,7 +1306,7 @@ def style_color_palette_diverging():
id_vars=["time"],
value_vars=data.columns[1:],
value_name="y",
var_name=["grouping"],
var_name="grouping",
)

# Plot the data
Expand Down
6 changes: 3 additions & 3 deletions docs/_static/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/Examples.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -4908,7 +4908,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.13"
"version": "3.9.2"
},
"toc": {
"nav_menu": {},
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Pillow>=9.1.0
# Avoid selenium bug:
# https://github.com/SeleniumHQ/selenium/issues/5296
selenium>=4.0.0
bokeh>=3.0.0
bokeh>=3.4.2
scipy>=1.6.0
ipykernel>=6.0
ipython>=7.17.0
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ def find_meta(meta):
'Development Status :: 4 - Beta',
'Intended Audience :: Science/Research',
'Natural Language :: English',
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"License :: OSI Approved :: Apache Software License"
],
test_suite='tests',
tests_require=test_requirements,
setup_requires=setup_requirements,
python_requires='>=3.8,<4',
python_requires='>=3.9,<4',
license="Apache 2")
Loading
Loading