Define global config values for plotly's Figure show method - python

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?

Related

Plotly Object displays as blank in DataBricks

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)

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.

plt.show() does nothing when used for the second time

I am just starting to learn data science using python on Data Camp and I noticed something while using the functions in matplotlib.pyplot
import matplotlib.pyplot as plt
year = [1500, 1600, 1700, 1800, 1900, 2000]
pop = [458, 580, 682, 1000, 1650, 6,127]
plt.plot(year, pop)
plt.show() # Here a window opens up and shows the figure for the first time
but when I try to show it again it doesn't..
plt.show() # for the second time.. nothing happens
And I have to retype the line above the show() to be able to show a figure again
Is this the normal thing or a problem?
Note: I am using the REPL
Answer
Yes, this is normal expected behavior for matplotlib figures.
Explanation
When you run plt.plot(...) you create on the one hand the lines instance of the actual plot:
>>> print( plt.plot(year, pop) )
[<matplotlib.lines.Line2D object at 0x000000000D8FDB00>]
...and on the other hand a Figure instance, which is set as the 'current figure' and accessible through plt.gcf() (short for "get current figure"):
>>> print( plt.gcf() )
Figure(432x288)
The lines (as well as other plot elements you might add) are all placed in the current figure. When plt.show() is called, the current figure is displayed and then emptied (!), which is why a second call of plt.show() doesn't plot anything.
Standard Workaround
One way of solving this is to explicitly keep hold of the current Figure instance and then show it directly with fig.show(), like this:
plt.plot(year, pop)
fig = plt.gcf() # Grabs the current figure
plt.show() # Shows plot
plt.show() # Does nothing
fig.show() # Shows plot again
fig.show() # Shows plot again...
A more commonly used alternative is to initialize the current figure explicitly in the beginning, prior to any plotting commands.
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
fig.show() # Shows plot again
This is often combined with the specification of some additional parameters for the figure, for example:
fig = plt.figure(figsize=(8,8))
For Jupyter Notebook Users
The fig.show() approach may not work in the context of Jupyter Notebooks and may instead produce the following warning and not show the plot:
C:\redacted\path\lib\site-packages\matplotlib\figure.py:459:
UserWarning: matplotlib is currently using a non-GUI backend, so
cannot show the figure
Fortunately, simply writing fig at the end of a code cell (instead of fig.show()) will push the figure to the cell's output and display it anyway. If you need to display it multiple times from within the same code cell, you can achieve the same effect using the display function:
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
plt.show() # Does nothing
from IPython.display import display
display(fig) # Shows plot again
display(fig) # Shows plot again...
Making Use of Functions
One reason for wanting to show a figure multiple times is to make a variety of different modifications each time. This can be done using the fig approach discussed above but for more extensive plot definitions it is often easier to simply wrap the base figure in a function and call it repeatedly.
Example:
def my_plot(year, pop):
plt.plot(year, pop)
plt.xlabel("year")
plt.ylabel("population")
my_plot(year, pop)
plt.show() # Shows plot
my_plot(year, pop)
plt.show() # Shows plot again
my_plot(year, pop)
plt.title("demographics plot")
plt.show() # Shows plot again, this time with title
Using command:
%matplotlib
in ipython3 help me to use separate window with plot
Start ipython3 and issue the commands:
import matplotlib.pyplot as plt
%matplotlib #plot in separate window
fig, ax = plt.subplots() #Appear empty Tcl window for image
ax.plot([1, 2, 3, 4], [5, 6, 7, 8]) #Appear graph in window
In some version of matplotlib, fig.show() does not block the window for showing plot multiple times. so, Quick fixes using self.fig.waitforbuttonpress() it waits user to press the button for next plot visualisation.
self.fig.show()
plt.pause(0.1)
self.fig.waitforbuttonpress()

How to suppress seaborn output when recalling figure object with regplot

I am trying to plot data to a figure and respective axis in matplotlib and as new work comes up, recall the figure with the additional plot on the axis:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
x=np.arange(0,20)
y=2*x
fig,ax=plt.subplots()
ax.scatter(x,x)
ax.scatter(x,y)
fig
Which works fine with matplotlib, if I however use seaborn's regplot:
fig2,ax2=plt.subplots()
sns.regplot(x,x,ax=ax2,fit_reg=False)
sns.regplot(x,y,ax=ax2,fit_reg=False)
fig2
fig2 generates the figure that I want but the regplot command generates an empty figure. Is there a way to suppress the regplot's empty output or have it display the updated ax2 without recalling fig2?
It seems you are using the jupyter notebook with the inline backend. In some circumstances regplot triggers the creation of a new figure even if the artists are being added to the previous one and this messes up the output. I don't know why this happens but I found a workaround that might help you, using plt.ioff to temporarily disable automatic display of figures.
plt.ioff()
fig, ax = plt.subplots()
sns.regplot(x, x, ax=ax)
fig
sns.regplot(x, 2 * x, ax=ax)
fig
You have to call plt.ioff before creating the figure for this to work. After that you have to explicitly display the figure. Then you can call plt.ion to restore the default behaviour.
regplot does not generate an empty figure. According to the documentation:
Understanding the difference between regplot() and lmplot() can be a
bit tricky. In fact, they are closely related, as lmplot() uses
regplot() internally and takes most of its parameters. However,
regplot() is an axes-level function, so it draws directly onto an axes
(either the currently active axes or the one provided by the ax
parameter), while lmplot() is a figure-level function and creates its
own figure, which is managed through a FacetGrid.
When I do the following:
fig2,ax2 = plt.subplots()
same_fig2 = sns.regplot(x,x,ax=ax2,fit_reg=False)
same_fig2.figure is fig2
>>> True

When is matplotlib's pyplot.figure redundant?

From my understanding of matplotlib, the figure method creates a new, blank figure, basically a "white canvas," and via, for example, plot I can add the actual plot. The show method then clears the figure:
import matplotlib.pyplot as plt
fig = plt.figure()
plt.plot([0, 1], [0, 1])
plt.show()
1) Now, I am wondering why the same can be achieved when no figure was created. More specifically, I am wondering how matplotlib handles this internally.
2) Is there any advantage in using plt.figure if I don't intend to manipulate figure objects?
import matplotlib.pyplot as plt
plt.plot([0, 1], [0, 1])
plt.show()
plt.plot internally calls gca (get current axes) which then calls gcf (get current figure), which returns the current (last used) figure. If there is no current figure it calls plt.figure and returns the newly created figure. So yes, weather or not you call plt.figure yourself doesn't really matter. I wouldn't say it is redundant (since it has to be done), but you can safely let matplotlib take care of it.
Directly calling plt.figure if you don't intend to manipulate the figure or pass arguments to the constructor is only useful to create multiple figures to show them simultaneously when calling plt.show.
plt.figure()
plt.plot(1,1,'x')
plt.figure()
plt.plot(2,2,'o')
plt.show()

Categories

Resources