Plotly Object displays as blank in DataBricks - python

I have a plotly object that should be showing up properly but for some reason it only shows up blank in DataBricks. The object type is:
plotly.graph_objs._figure.Figure
I have tried the following to display the figure:
fig.show()
display(fig)
displayHTML(fig.to_html())
All possible solutions I can think of result in the same thing. Thanks!
Btw... Using Plotly Version 4.9

Try using the plot method from plotly.offline. This following is from DataBricks documentation, but Jupyter notebooks have a similar issue where a Plotly graph_object Figure won't render unless you use plotly.offline.
from plotly.offline import plot
import plotly.graph_objects as go
# Instead of simply calling plot(...), store your plot as a variable and pass it to displayHTML().
# Make sure to specify output_type='div' as a keyword argument.
# (Note that if you call displayHTML() multiple times in the same cell, only the last will take effect.)
p = plot(
[ ## define your go.Figure here ##
],
output_type='div'
)
displayHTML(p)

Worth noting that you can similarly use the plot method from plotly.offline to display plotly.express plots.
This saves a lot of code for simple plots where graph_objects are overkill!
from plotly.offline import plot
import plotly.express as px
p = plot(
px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16]),
output_type='div'
)
displayHTML(p)

Related

Blank Bar Charts in Plotly

I have a df - Wards - that contains the number of different events that happen on each ward of a hospital. I just want a simple bar chart of the totals of these events. I have used plotly before - I am no means an expert (evidently!) but I can't figure out where I am going wrong! With the code below I am seeing anything with fig.show(). I added the fig.write_image command to test - this returns the correct graph - but I can't figure out why my fig.show() command doesn't work
import plotly.express as px
import matplotlib.pyplot as plt
fig = px.bar(Wards, x='Ward', y='Total_Tasks')
fig.write_image("fig1.png")
fig.show()
I tried to duplicate your code but of course I don't have the data, so I made some up and I also didn't know for sure what modules you are importing, so I used the help at:
https://plotly.com/python/getting-started/
but anyway, here is what I came up with
that seems to work.
import plotly.express as px
import matplotlib.pyplot as plt
fig = px.bar(x=["a", "b", "c"], y=[1, 3, 2])
plt.savefig('fig1.png',bbox_inches="tight",dpi=600)
fig.show()

Define global config values for plotly's Figure show method

A plotly Figure has show() method which accepts a config argument, as per documentation
import plotly.graph_objects as go
fig = go.Figure()
config = dict({'scrollZoom': True})
fig.add_trace(
go.Scatter(
x=[1, 2, 3],
y=[1, 3, 1]))
fig.show(config=config)
This can be quite tedious, as I have to catch the Figure and show it with the show method instead of normal usage.
Instead of just doing
px.line(df)
Now I have to
fig = px.line(df)
fig.show(config=config)
In all charts.
Is there a way through the Plotly library to define the config values globally, so that I can call px.line without setting the config per Figure instance, and I dont have to create a custom wrapper?

Set up seaborn/matplotlib to always use edgecolor='k' parameter

I am constructing a lot of bar plots which are all in the same style, for example
import seaborn as sns
import matplotlib.pyplot as plt
sns.set_style('darkgrid')
# some more configuration options that work as expected here
sns.barplot([1, 2, 3], [4, 5, 6], edgecolor='k')
which gives
Is there a way to configure my plotting environment to always use edgecolor='k' such that I don't have to pass the parameter every time?
I tried
sns.set_style(rc={'patch.force_edgecolor':True})
but it has no effect. If I don't explicitly use edgecolor='k' when plotting then the bars don't have an edge.
I also noticed that there is
plt.rc('edgecolor', ???)
but I cannot figure out what to pass for ??? (it has to be a keyword argument).
edit:
Using
sns.set_style(rc={'patch.force_edgecolor':True})
does not work, but using
sns.set_style(rc={'patch.force_edgecolor':True,
'patch.edgecolor': 'black'})
works as expected. I don't understand why 'patch.edgecolor': 'black' is necessary here since this seems to be the default setting.
Use patch, as in:
plt.rcParams['patch.edgecolor'] = 'black'
You can also do:
plt.rc('patch', edgecolor='black')
I can now explain what went wrong with sns.set_style.
sns.set_style('darkgrid') sets 'patch.edgecolor' to 'w', that's why it has to be manually set to 'black' again.

Python converting waterfall figure to plotly

I am using the waterfall_chart package in Python to create a waterfall figure. The package mainly uses matplotlib in the backend, so I was trying to use the tls.mpl_to_plotly(mpl_fig) function to covert the matplotlib figure into plotly. But when converting, an error pops up. Is there a way to convert waterfall_chart into plotly or is there an easy way to create the chart directly in plotly? I saw some previous discussion on similar chart in plotly, but it involved pretty manual coding of the chart number.
You could use the following code to recreate the chart.
import waterfall_chart
import matplotlib.pyplot as plt
import plotly.tools as tls
a = ['sales','returns','credit fees','rebates','late charges','shipping']
b = [10,-30,-7.5,-25,95,-7]
mpl_fig = plt.figure()
waterfall_chart.plot(a, b)
plt.show()
waterfall chart
But when I try to convert to plotly using mpl_to_plotly(), there is an error:
plotly_fig = tls.mpl_to_plotly(mpl_fig)
ValueError: min() arg is an empty sequence
The detail of the waterfall_chart package could be found here: https://github.com/chrispaulca/waterfall/blob/master/waterfall_chart.py
My answer addresses
[...] or is there an easy way to create the chart directly in plotly?
With newer versions of plotly you can use plotly.graph_objs.Waterfall.
Below is a basic example with your data sample with a setup that uses iplot in an off-line Jupyter Notebook:
Plot:
Code:
# imports
import plotly
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
from IPython.core.display import display, HTML
import plotly.figure_factory as ff
import plotly.graph_objs as go
import pandas as pd
import numpy as np
# setup
display(HTML("<style>.container { width:35% !important; } .widget-select > select {background-color: gainsboro;}</style>"))
init_notebook_mode(connected=True)
np.random.seed(1)
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected = False)
# your values
a = ['sales','returns','credit fees','rebates','late charges','shipping']
b = [10,-30,-7.5,-25,95,-7]
# waterfall trace
trace = go.Waterfall(
x = a,
textposition = "outside",
text = [str(elem) for elem in b],
y = b,
connector = {"line":{"color":"rgb(63, 63, 63)"}},
)
layout = go.Layout(
title = "Waterfall chart, plotly version 3.9.0",
showlegend = True
)
iplot(go.Figure([trace], layout))
Check your version with:
import plotly
plotly.__version__
Update your version in a cmd console using:
pip install plotly --upgrade
List a has a length of 6, list b has a length of 5.
Matplotlib refuses to display an empty array, list or whatever.
Solve it to add a number or 0 to b or add an if to your code, to avoid matplotlib gets an empty sequence.

Updating a chart with Plotly offline with Python

I am using Plotly offline on Jupyter.
I am plotting curves:
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
from plotly.graph_objs import *
import datetime as dt
list_date = [dt.datetime(2016,1,1).date(), dt.datetime(2016,1,2).date(), dt.datetime(2016,1,3).date(), dt.datetime(2016,1,4).date()]
data = []
for i in range(3) :
list = [i/2+1, i/2+2, i/2+3, i/2+4]
data.append(Scatter(x=list_date, y=list, name='y'+str(i)))
figure = Figure(data=data)
iplot(figure)
And I get a very nice graph!
In the latter case, the user wants to add a bar graph on it (in addition to the two lines already there).
list_bar = [0.5, 1.5, 2.5, 3.5]
data = [Bar(x=list_date, y=list_bar, name='bar')]
figure.update(data=data)
iplot(figure)
But I have only the bar chart, not the previous 2 lines. How to have offline the equivalent of the online function fileopt='append'?
py.plot(data, filename='append plot', fileopt='append')
In the latest plotly version 3, a FigureWidget has been added specifically to handle your problem of wanting to update an existing offline figure.
For me, running pip install plotly --upgrade got me the latest version within my Anaconda environment.
I've modified your example code below to use the new FigureWidget, and left in your old code that needed changing with comments. The new FigureWidget is meant to be compatible with the ordinary Figure that you were using.
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
from plotly.graph_objs import *
import datetime as dt
# list_date = [dt.datetime(2016,1,1).date(), dt.datetime(2016,1,2).date(), dt.datetime(2016,1,3).date(), dt.datetime(2016,1,4).date()]
list_date = [dt.datetime(2016,1,1), dt.datetime(2016,1,2), dt.datetime(2016,1,3), dt.datetime(2016,1,4)]
data = []
for i in range(3) :
list = [i/2+1, i/2+2, i/2+3, i/2+4]
data.append(Scatter(x=list_date, y=list, name='y'+str(i)))
# figure = Figure(data=data)
# iplot(figure)
figure = FigureWidget(data=data)
figure
I've commented out the portions that were changed so you can see them for reference.
One other thing to note, due to a problem within ipykernel.json_util, the json_clean function that serializes Plotly JSON objects to show on your Jupyter screen doesn't know what to do with a datetime.date object -- only datetime objects. If you don't remove the .date you will get an exception and no graph. I'm guessing this would happen for datetime.time objects as well because it seems it is also unhandled in the current ipykernel code.
When you're ready to run your updated code, you simple create your data and use the add_trace function:
list_bar = [0.5, 1.5, 2.5, 3.5]
figure.add_trace(Bar(x=list_date, y=list_bar, name='bar'))
And your plot automatically updates in the previous cell with the added trace.
Lastly, there's a good guide about the new FigureWidget for those interested.

Categories

Resources