Bokeh's to_bokeh() ignores legend from matplotlib - python

When converting a matplotlib plot into a bokeh html plot, I see that the legend in the matplotlib plot does not appear in the bokeh html plot. Below is an example. How can I get the legend to show up in bokeh? Thanks.
import matplotlib.pyplot as plt
from bokeh.plotting import figure, show, output_file, save
from bokeh.mpl import to_bokeh
if __name__ == '__main__':
legend = ['x^2', '2x']
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(range(10), [x*x for x in range(10)], '-o')
plt.plot(range(10), [2*x for x in range(10)], '-o')
plt.legend(legend, loc='upper left')
plt.show()
bk = to_bokeh(fig)
show(bk
)

UPDATE: Please note Bokeh's current MPL compat has been deprecated and will be removed completely for Bokeh 1.0 release.
If MEP25 is ever implementented, it's possible MPL combat could return as a separate, add-on package.
Bokeh's MPL compat capability is based on an experimental third-party library that is no longer actively maintained. The to_bokeh functionality is provided as-is, and with the explicit expectation that it currently provides only partial coverage. More comprehensive compatibility will depend on the implementation of Matplotlib Enhancement Proposal 25 which would provide a stable and robust JSON serialization protocol for libraries like Bokeh to be able to interoperate with it. No work will be done on Bokeh's MPL compat until or if MEP25 is implemented. However, there has been no significant movement on MEP 25 in two years, so my strong recommendation, if you are looking to take advantage of Bokeh's features, is to use native Bokeh APIs such as bokeh.plotting directly, and to not rely on to_bokeh for anything serious.

Related

Matplotlib performance on pan

I working on a PyQt GUI in order to plot 2D/3D data.
Matplotlib is very interesting concerning all its available features.
However, Matplotlib seems to not be relevant when you have huge amount of data (for instance 10000x10000). I found that maybe GTKAgg backend is really efficient for this issue, but not really.
Maybe you can help me in order to enhance the performance of matplotlib when you want to pan or zoom in the figure.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mpl.use('GTK3Agg')
fig, ax = plt.subplots()
n = 10000
Z = np.random.randint(10,size=(n,n))
ax.imshow(Z)
plt.show()

Is there a way to change the ticks for ALL the future plots with matplotlibs

I have an unusual request, but I have a question that has been bothering me for some time regarding matplotlib.
When I plot figures, even with the basic commands, for example (example), my plots do not have the same look. That is to say that in my case the ticks are systematically on the outside and only on the left and bottom edges, see:
My plot with outside ticks + only 2 axis with ticks on.
However, while looking at some ppl plots, they don't look like this, and they systematically have the four sides with ticks that are pointing inside the plot:
Plot from someone giving tips on stackoverflow
I know how to modify this for a single particular plot. But I would like to know if there is a way to specify somewhere that all my plots should have this style.
Is it possible to do so?
You can patch the Figure.add_subplot method and put your customization in there. For example:
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
_original_add_subplot = Figure.add_subplot
def new_add_subplot(*args, **kwargs):
ax = _original_add_subplot(*args, **kwargs)
ax.tick_params(left='on', right='on', top='on', bottom='on')
return ax
Figure.add_subplot = new_add_subplot
fig, ax = plt.subplots()
ax.axline((0,0), slope=1)
plt.show()
Then you could put all this in a separate package which would execute this when imported. So all you would need to do is import mplcustom. If that's still too much work, you can also put the code into sitecustomize or usercustomize modules, which will be imported automatically on startup (see Site-specific configuration hook for more information).

How to set our own yticks on a graph?

I want to increase the yticks upto 100. It is currently 80 but i want it to be 100.
plt.yticks(np.arange(0,100,10))
but this doesn't work.
A couple of things:
using pyplot isn't recommended (but is still possible for the sake of backwards compatibility)
setting the ticks or tick labels isn't recommended as those solutions fall apart when the axes limits changes.
So the solution is to
use the object-oriented interface
set the locator and limits directly
from matplotlib import pyplot
from matplotlib import ticker
fig, ax = pyplot.subplots(figsize=(6, 4))
ax.bar(...)
# or df.plot.bar(..., ax=ax)
ax.yaxis.set_major_locator(ticker.MultipleLocator(10))
ax.set_ylim(bottom=0, top=100)

Python: How to plot y=cosh(x) *cos(5x)

using Python I would like to plot a curve for the function y=cosh(x)*cos(5x) in my Jupyter Notebook.
In other words:
(cosine hyperbolicus of x) times (cosine of 5x)
How do I do this?
What do I need to import?
Thank you very much in advance.
Greetings
Specify the range of values for x that you need.
You can use Seaborn on top of Matplotlib to make it prettier, but this is optional:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-5,5,0.1) # start,stop,step
y= (np.cosh(x))*(np.cos(5*x) )
# set a grey background (use sns.set_theme() if seaborn version 0.11.0 or above)
sns.set(style="darkgrid")
plt.plot(x,y)
plt.show()
You will need to import a plotting library and a maths library. The most commonly used plotting library is matplotlib, and for maths it's numpy. For plotting, bokeh is a an alternative to matplotlib, which I think is great because graphs are interactive by default. The disadvantage is that because it's not as widely used as matplotlib, you're less likely to find help on it in terms of StackOverflow answers and tutorials.
Anyway, to the code:
# Import the necessary packages and modules
import matplotlib.pyplot as plt
import numpy as np
# Set your x-range and calculate y
xmin = -2.5
xmax = 2.5
numPoints = 100
x = np.linspace(xmin, xmax, numPoints)
y = np.cosh(x)*np.cos(5*x)
# Plot -- it really can be this simple [1]
plt.plot(x,y)
Both of the graphing libraries above give you flexible options on where to place the axes, legends, titles, and so on. I recommend searching for beginner's tutorials on them to learn this stuff in depth.
[1] There are two ways to plot in matplotlib. What is shown here is the MATLAB-like interface. The other method is to use the object-based interface, which takes a bit more of getting used to, and requires a bit more boilerplate code, but that's what you will end up using once you demand more control over the appearance of your plots.
I recommend starting with the MATLAB-like commands first. The documentation has a good beginner's tutorial: https://matplotlib.org/stable/tutorials/introductory/pyplot.html

seaborn in jupyter notebook: why does sns.despine() work for lmplot but not regplot?

Jupyter notebook, using Python 3:
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.despine()
then
snstest1 = sns.regplot(x="foo", y="bar", data=my_data)
shows a plot with the unwanted border box (i.e., sns.despine() doesn't seem to have affected it).
but:
snstest2 = sns.lmplot(x="foo", y="bar", data=my_data)
shows a plot with the unwanted border box correctly removed.
The only documentation I can find that seems to bear directly on this is the following, from the api docs for regplot:
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. This has a few
consequences, namely that regplot() can happily coexist in a figure
with other kinds of plots and will follow the global matplotlib color
cycle. In contrast, lmplot() needs to occupy an entire figure, and the
size and color cycle are controlled through function parameters,
ignoring the global defaults.
But I don't fully understand the difference between a "figure" and an "axis." The best guess I can make without knowing the underlying model here is that when these weird global-state-mutating functions built into Seaborn, like despine and (?) set_palette and such, are active, only "figures," not "axes," check that state before rendering? But if that's so, how would I get something that generates an "axis" to plot in accordance with what I've requested?
In short: Call sns.despine after your plotting function.
The longer version:
lmplot creates its own figure. But it does not need despine. It will do it automatically, even without calling sns.despine.
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.lmplot(x="total_bill", y="tip", data=tips)
plt.show()
This is the reason the code from the question actually seems to work.
However, what is really happening is that if you call sns.despine before any figure is created, it will act on a newly created figure. The code from the question is hence creating two figures. One, which is empty, but also is "despined" and then one which is the lmplot figure and which is "despined" because every lmplot is despined by default.
A regplot is instead created in an axes of a matplotlib figure. If no figure or axes is provided, it will create a new one. This means that sns.despine needs to know which axes to despine. If you call it before anything else, there will again be two figures: One, which is empty, but also is "despined" and then one which is the regplot figure. This figures axes are not "despined", because noone told them so.
So the idea is of course to call sns.despine after creating the plot. You may specify which figure or axes to despine as argument (sns.despine(ax=ax))
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
ax = sns.regplot(x="total_bill", y="tip", data=tips)
sns.despine(ax=ax)
plt.show()
but if you only have a single subplot that wouldn't even be necessary. Hence
tips = sns.load_dataset("tips")
sns.regplot(x="total_bill", y="tip", data=tips)
sns.despine()
will work equally well and produce

Categories