zeppelin/interpreter/lib/python/mpl_config.py
Prabhjyot Singh 89e2e0246c [ZEPPELIN-2827] Spark's pyspark fails if unsupported version of matplotlib is present
### What is this PR for?
%spark.pyspark paragraphs keep running for more than > 5 minutes and then at the end, throw TTransportException.

```
org.apache.thrift.transport.TTransportException
	at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:132)
	at org.apache.thrift.transport.TTransport.readAll(TTransport.java:86)
	at org.apache.thrift.protocol.TBinaryProtocol.readAll(TBinaryProtocol.java:429)
	at org.apache.thrift.protocol.TBinaryProtocol.readI32(TBinaryProtocol.java:318)
	at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:219)
	at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:69)
```

This happens because Zeppelin refers to `matplotlib.rcParams['savefig.format']` https://github.com/apache/zeppelin/blob/master/interpreter/lib/python/mpl_config.py#L83 which is only present in matplotlib 1.2.0 (https://github.com/matplotlib/matplotlib/blob/v1.2.0/matplotlibrc.template#L355) and onwards.

### What type of PR is it?
[Bug Fix]

### What is the Jira issue?
* [ZEPPELIN-2827](https://issues.apache.org/jira/browse/ZEPPELIN-2827)

### How should this be tested?
Try running spark.pyspark on a machine with matplotlib==1.1.1 installed, pyspark should work as expected.

### Questions:
* Does the licenses files need update? N/A
* Is there breaking changes for older versions? N/A
* Does this needs documentation? N/A

Author: Prabhjyot Singh <prabhjyotsingh@gmail.com>

Closes #2516 from prabhjyotsingh/ZEPPELIN-2827 and squashes the following commits:

0321fcd3e [Prabhjyot Singh] check if `savefig.format` exists in mpl_config.py
da26f5613 [Prabhjyot Singh] add a version check along with check if matplotlib is installed
2017-08-08 11:38:18 -07:00

105 lines
3.6 KiB
Python

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This module provides utitlites for users to configure the inline plotting
# backend through a PyZeppelinContext instance (eg, through z.configure_mpl())
import matplotlib
def configure(**kwargs):
"""
Generic configure function.
Usage: configure(prop1='foo', prop2='bar', ...)
Currently supported zeppelin-specific properties are:
interactive - If true show all figures without explicit call to show()
via a post-execute hook.
angular - If true, bind figures to angular display system.
close - If true, close all figures once shown.
width, height - Default width / height of the figure in pixels.
fontsize - Font size.
dpi - dpi of the figure.
fmt - Figure format
supported_formats - Supported Figure formats ()
context - ZeppelinContext instance (requires PY4J)
"""
_config.update(**kwargs)
# Broadcast relevant changes to matplotlib RC
_on_config_change()
def get(key):
"""
Get the configuration info given a key
"""
return _config[key]
def _on_config_change():
# dpi
dpi = _config['dpi']
# For older versions of matplotlib, savefig.dpi is not synced with
# figure.dpi by default
matplotlib.rcParams['figure.dpi'] = dpi
if matplotlib.__version__ < '2.0.0':
matplotlib.rcParams['savefig.dpi'] = dpi
# Width and height
width = float(_config['width']) / dpi
height = float(_config['height']) / dpi
matplotlib.rcParams['figure.figsize'] = (width, height)
# Font size
fontsize = _config['fontsize']
matplotlib.rcParams['font.size'] = fontsize
# Default Figure Format
fmt = _config['format']
supported_formats = _config['supported_formats']
if fmt not in supported_formats:
raise ValueError("Unsupported format %s" %fmt)
if matplotlib.__version__ < '1.2.0':
matplotlib.rcParams.update({'savefig.format': fmt})
else:
matplotlib.rcParams['savefig.format'] = fmt
# Interactive mode
interactive = _config['interactive']
matplotlib.interactive(interactive)
def _init_config():
dpi = matplotlib.rcParams['figure.dpi']
if matplotlib.__version__ < '1.2.0':
matplotlib.rcParams.update({'savefig.format': 'png'})
fmt = matplotlib.rcParams['savefig.format']
width, height = matplotlib.rcParams['figure.figsize']
fontsize = matplotlib.rcParams['font.size']
_config['dpi'] = dpi
_config['format'] = fmt
_config['width'] = width*dpi
_config['height'] = height*dpi
_config['fontsize'] = fontsize
_config['close'] = True
_config['interactive'] = matplotlib.is_interactive()
_config['angular'] = False
_config['supported_formats'] = ['png', 'jpg', 'svg']
_config['context'] = None
_config = {}
_init_config()