Skip to content

Commit

Permalink
[export] Repair ggplot graph rendering by switching to plotnine
Browse files Browse the repository at this point in the history
  • Loading branch information
amotl committed Aug 14, 2023
1 parent 6c32425 commit 1cfd4a5
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ in progress
- [docs] Refactor "decoders" section to "integrations", and improve index/overview page
- [export] Improve export capabilities by adding parameters ``sort``, ``direction``,
``limit``, and ``scalar``. Thanks, @ClemensGruber.
- [export] Repair ``ggplot`` graph rendering by switching to ``plotnine``


.. _kotori-0.27.0:
Expand Down
37 changes: 25 additions & 12 deletions kotori/io/export/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,18 +171,28 @@ def render_png(self, buffer):
"""


elif renderer == 'ggplot':

# https://yhat.github.io/ggplot/notebook.html?page=build/docs/examples/Multiple%20Line%20Plot.html
# https://stackoverflow.com/questions/23541497/is-there-a-way-to-plot-a-pandas-series-in-ggplot
# https://stackoverflow.com/questions/24478925/is-it-possible-to-plot-multiline-chart-on-python-ggplot/24479513#24479513

# https://github.com/yhat/ggplot/blob/master/docs/how-to/Building%20Faceted%20(or%20Trellised)%20Plots.ipynb
# https://github.com/yhat/ggplot/blob/master/docs/how-to/Annotating%20Plots%20-%20Titles%20and%20Labels.ipynb
# https://github.com/yhat/ggplot/blob/master/docs/how-to/How%20to%20make%20xkcd%20style%20graphs.ipynb
elif renderer in ['ggplot', 'plotnine']:
"""
Renderer based on ggplot, now in plotnine.
ggplot
======
- https://yhat.github.io/ggplot/notebook.html?page=build/docs/examples/Multiple%20Line%20Plot.html
- https://stackoverflow.com/questions/23541497/is-there-a-way-to-plot-a-pandas-series-in-ggplot
- https://stackoverflow.com/questions/24478925/is-it-possible-to-plot-multiline-chart-on-python-ggplot/24479513#24479513
- https://github.com/yhat/ggplot/blob/master/docs/how-to/Building%20Faceted%20(or%20Trellised)%20Plots.ipynb
- https://github.com/yhat/ggplot/blob/master/docs/how-to/Annotating%20Plots%20-%20Titles%20and%20Labels.ipynb
- https://github.com/yhat/ggplot/blob/master/docs/how-to/How%20to%20make%20xkcd%20style%20graphs.ipynb
plotnine
========
- https://github.com/has2k1/plotnine
- https://plotnine.readthedocs.io/
"""

from ggplot import ggplot, aes, qplot, geom_line, geom_text, ggtitle, stat_smooth, scale_x_date, date_format, date_breaks
from ggplot import theme_538, theme_bw, theme_gray, theme_xkcd
from plotnine import ggplot, aes, qplot, geom_line, geom_text, ggtitle, stat_smooth, scale_x_datetime
from plotnine import theme_538, theme_bw, theme_gray, theme_xkcd

# https://stackoverflow.com/questions/24478925/is-it-possible-to-plot-multiline-chart-on-python-ggplot/24479513#24479513
# https://stackoverflow.com/questions/23541497/is-there-a-way-to-plot-a-pandas-series-in-ggplot
Expand All @@ -196,9 +206,12 @@ def render_png(self, buffer):

plot = ggplot(df, aes(x='time', y='value', color='variable'))\
+ geom_line()\
+ scale_x_date(limits=(datetime_min, datetime_max), breaks=locator, labels=formatter)\
+ scale_x_datetime(limits=(datetime_min, datetime_max))\
+ ggtitle(bucket.title.human)

# FIXME: Currently croaks.
# + scale_x_date(limits=(datetime_min, datetime_max), breaks=locator, labels=formatter) \

# Axis labels
plot.xlab = 'Time'
plot.ylab = 'Value'
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
# Algorithms
# ----------
#'scipy>=1.4.1,<1.6',
'ggplot>=0.11.5,<0.12',
'plotnine<0.13',

# gfortran
# aptitude install libatlas-base-dev lapack-dev gfortran or
Expand Down
55 changes: 55 additions & 0 deletions test/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,58 @@ def test_export_hdf5(machinery, create_influxdb, reset_influxdb):
assert hdf["/itest_foo_bar/table"][()] == array(
[(1583810982000000000, 51.8, 25.26)],
dtype=[('index', '<i8'), ('humidity', '<f8'), ('temperature', '<f8')])


@pytest_twisted.inlineCallbacks
@pytest.mark.http
@pytest.mark.export
def test_export_png(machinery, create_influxdb, reset_influxdb):
"""
Verify `sort` and `direction` transformation parameters of HTTP export API.
"""

# Submit two measurements, with timestamp.
data = {
'time': 1583810982,
'temperature': 25.26,
'humidity': 51.8,
}
yield threads.deferToThread(http_json_sensor, settings.channel_path_data, data)

data = {
'time': 1583810993,
'temperature': 32.26,
'humidity': 64.8,
}
yield threads.deferToThread(http_json_sensor, settings.channel_path_data, data)

# Wait for some time to process the message.
yield sleep(PROCESS_DELAY_MQTT)

# PNG: matplotlib.
deferred = threads.deferToThread(http_get_data, settings.channel_path_data, format="png", params={
"from": ts_from,
"to": ts_to,
#"renderer": "ggplot",
})
yield deferred
assert deferred.result.startswith(b"\x89PNG")

# PNG: ggplot.
deferred = threads.deferToThread(http_get_data, settings.channel_path_data, format="png", params={
"from": ts_from,
"to": ts_to,
"renderer": "ggplot",
})
yield deferred
assert deferred.result.startswith(b"\x89PNG")

# PNG: ggplot/xkcd.
deferred = threads.deferToThread(http_get_data, settings.channel_path_data, format="png", params={
"from": ts_from,
"to": ts_to,
"renderer": "ggplot",
"theme": "xkcd",
})
yield deferred
assert deferred.result.startswith(b"\x89PNG")

0 comments on commit 1cfd4a5

Please sign in to comment.