Open heoa opened 5 years ago
I believe that is not supported in plotnine. You can of course asked the plotly people to add a feature like that. I guess it would be a cool addition. Meanwhile you might want to have a look at altair, which also has a grammar of graphics approach and directly renders to interactive HTML plots.
Just discovered that plotly even supports conversion from matplotlib figures to plotly objects, see https://plot.ly/matplotlib/getting-started/. However, that does not seem to work with the figures created by plotnine.
... However, that does not seem to work with the figures created by plotnine.
I have not used plotly but I would have expected it to work (may be not perfectly) with figures created in plotnine, since it is all matplotlib.
FWIW - here are examples of a working matplotlib graph and a failing plotnine graph. I do get a graph but no data. The key message appears to be:
Dang! That path collection is out of this world. I totally don't know what to do with it yet! Plotly can only import path collections linked to 'data' coordinates
The working matplotlib graph:
import dash_core_components as dcc
import dash_html_components as html
from plotly.tools import mpl_to_plotly
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import numpy as np
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
n = 50
x, y, z, s, ew = np.random.rand(5, n)
c, ec = np.random.rand(2, n, 4)
area_scale, width_scale = 500, 5
fig, ax = plt.subplots()
sc = ax.scatter(x, y, c=c,
s=np.square(s)*area_scale,
edgecolor=ec,
linewidth=ew*width_scale)
ax.grid()
plotly_fig = mpl_to_plotly(plt.gcf())
graph = dcc.Graph(id='myGraph', figure=plotly_fig)
app.layout = html.Div([graph])
if __name__ == '__main__':
app.run_server(debug=True)
The failing plotnine graph:
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from plotly.tools import mpl_to_plotly
from plotnine import *
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
# plotnine example from gallery
# https://plotnine.readthedocs.io/en/stable/generated/plotnine.geoms.geom_col.html#two-variable-bar-plot
df = pd.DataFrame({
'variable': ['gender', 'gender', 'age', 'age', 'age', 'income', 'income', 'income', 'income'],
'category': ['Female', 'Male', '1-24', '25-54', '55+', 'Lo', 'Lo-Med', 'Med', 'High'],
'value': [60, 40, 50, 30, 20, 10, 25, 25, 40],
})
df['variable'] = pd.Categorical(df['variable'], categories=['gender', 'age', 'income'])
graph = ggplot(df, aes(x='variable', y='value', fill='category')) + geom_col()
# get matplotlib figure
fig = graph.draw()
# dash graph
plotly_fig = mpl_to_plotly(fig)
graph = dcc.Graph(id='myGraph', figure=plotly_fig)
app.layout = html.Div([graph])
if __name__ == '__main__':
app.run_server(debug=True)
This is the error from running the dash app:
/home/mneilly/PycharmProjects/plotly/venv/bin/python /home/mneilly/PycharmProjects/plotly/plotlyplotnineexample.py
/home/mneilly/PycharmProjects/plotly/venv/lib/python3.6/site-packages/plotly/matplotlylib/renderer.py:451: UserWarning:
Dang! That path collection is out of this world. I totally don't know what to do with it yet! Plotly can only import path collections linked to 'data' coordinates
Running on http://127.0.0.1:8050/
Debugger PIN: 573-582-988
* Serving Flask app "plotlyplotnineexample" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
Running on http://127.0.0.1:8050/
Debugger PIN: 075-361-477
/home/mneilly/PycharmProjects/plotly/venv/lib/python3.6/site-packages/plotly/matplotlylib/renderer.py:451: UserWarning:
Dang! That path collection is out of this world. I totally don't know what to do with it yet! Plotly can only import path collections linked to 'data' coordinates
Which results in a blank graph:
Actually, this example appears to work:
import dash
import dash_core_components as dcc
import dash_html_components as html
from plotnine import *
from plotnine.data import *
from plotly.tools import mpl_to_plotly
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
p = ggplot(aes(x='displ', y='cty'), mpg)
p += geom_point()
# get matplotlib figure
fig = p.draw()
# dash graph
plotly_fig = mpl_to_plotly(fig)
graph = dcc.Graph(id='myGraph', figure=plotly_fig)
app.layout = html.Div([graph])
if __name__ == '__main__':
app.run_server(debug=True)
FYI/FWIW - regarding the conversion of matplotlib to plotly.
@mneilly-et, thanks for that link. Then I think best solution would be to have Plotly as a separate backend. It would be a lot of work, but it is worth thinking about; including the non-technical issues like copyright and licensing.
@has2k1 it would be a really awesome feature for plotnine
, but for sure there is a lot of work involved
FYI you can easily export plotnine to interactive HTML plots using mpld3.
@krassowski have you tried rendering with mpld3 in dash? I have attempted the following (within a callback to fill a div child target):
@app.callback(Output('graph1','children'), [Input("tenor1", "value")])
def update_graph(value):
Tbase = pd.to_datetime("2010-1-1")
dates = [Tbase + pd.DateOffset(days=10*i) for i in range(0,230)]
s1 = pd.Series(np.random.normal(0.2, 1.0, 230)).cumsum()
s2 = pd.Series(np.random.normal(0.0, 1.0, 230)).cumsum()
df = pd.concat([
pd.DataFrame({'date': dates, 'value': s1, 'what': 'strategy'}),
pd.DataFrame({'date': dates, 'value': s2, 'what': 'spy'}),
])
v = (ggplot() +
geom_line(aes(x='date', y='value', color='what'), data=df))
# use mpld3 to render the graph to html
fhtml = fig_to_html(v.draw())
return dash_dangerously_set_inner_html.DangerouslySetInnerHTML(fhtml)
Where the target is just:
html.Div(id='graph1')
I can see that the Githubissues.
In R, Plotly has added ggplot2 bindings to export to interactive plotly objects, more here. In Python, I want to use ggplot2 -style plotting so I chose Plotnine but I cannot find a way to generate interactive Plotly plots from Plotnine.
In Python, how can I generate interactive plots in Plotnine (interactive like in Plotly so easy to export to HTML for visual investigation)?