How to get the matplotlib inline output via jupyter_client - matplotlib

I try to use jupyter_client to get the matplotlib output and display it in my web app. Here's what I did. But io.stdout is just a string. How can I get the actual image data of matplotlib. Thanks
In [6]: with capture_output() as io:
...: reply = kc.execute_interactive("import matplotlib.pyplot as plt\n%matplotlib inline\ndata=[1,1,2,3,4]\nplt.figure()\nplt.plot(data)", timeout=TI
...: MEOUT)
...:
...:
In [8]: io.stdout
Out[8]: '[<matplotlib.lines.Line2D at 0x1086a8d30>]<matplotlib.figure.Figure at 0x106f220f0>'

Related

I have problems to replace inf and -inf win nan in pandas

I found a code on the web to replace inf and -inf with np.nan, however it did not work on my computer.
df = pd.DataFrame({"A" : [4.6, 5., np.inf]})
new_dataframe = a_dataframe.replace([np.inf, -np.inf], np.nan)
df
My output
A
0 4.6
1 5.0
2 inf
Does somebody know a solution?
import pandas and numpy, then assign to the dataframe df.replace([np.inf, -np.inf], np.nan). When you do df.replace([np.inf, -np.inf], np.nan) this does not update the dataframe it needs to be assigned with = for the change to happen.
Also, for some reason in the code you provided there is new_dataframe and a_dataframe, which have nothing to do with df. Try the code below.
import pandas as pd
import numpy as np
df = pd.DataFrame({"A": [4.6, 5., np.inf]})
df = df.replace([np.inf, -np.inf], np.nan)
print(df)

How to start Seaborn Logarithmic Barplot at y=1

I have a problem figuring out how to have Seaborn show the right values in a logarithmic barplot. A value of mine should be, in the ideal case, be 1. My dataseries (5,2,1,0.5,0.2) has a set of values that deviate from unity and I want to visualize these in a logarithmic barplot. However, when plotting this in the standard log-barplot it shows the following:
But the values under one are shown to increase from -infinity to their value, whilst the real values ought to look like this:
Strangely enough, I was unable to find a Seaborn, Pandas or Matplotlib attribute to "snap" to a different horizontal axis or "align" or ymin/ymax. I have a feeling I am unable to find it because I can't find the terms to shove down my favorite search engine. Some semi-solutions I found just did not match what I was looking for or did not have either xaxis = 1 or a ylog. A try that uses some jank Matplotlib lines:
If someone knows the right terms or a solution, thank you in advance.
Here are the Jupyter cells I used:
{1}
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
data = {'X': ['A','B','C','D','E'], 'Y': [5,2,1,0.5,0.2]}
df = pd.DataFrame(data)
{2}
%matplotlib widget
g = sns.catplot(data=df, kind="bar", y = "Y", x = "X", log = True)
{3}
%matplotlib widget
plt.vlines(x=data['X'], ymin=1, ymax=data['Y'])
You could let the bars start at 1 instead of at 0. You'll need to use sns.barplot directly.
The example code subtracts 1 of all y-values and sets the bar bottom at 1.
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import seaborn as sns
import pandas as pd
import numpy as np
data = {'X': ['A', 'B', 'C', 'D', 'E'], 'Y': [5, 2, 1, 0.5, 0.2]}
df = pd.DataFrame(data)
ax = sns.barplot(y=df["Y"] - 1, x=df["X"], bottom=1, log=True, palette='flare_r')
ax.axhline(y=1, c='k')
# change the y-ticks, as the default shows too few in this case
ax.set_yticks(np.append(np.arange(.2, .8, .1), np.arange(1, 7, 1)), minor=False)
ax.set_yticks(np.arange(.3, 6, .1), minor=True)
ax.yaxis.set_major_formatter(lambda x, pos: f'{x:.0f}' if x >= 1 else f'{x:.1f}')
ax.yaxis.set_minor_formatter(NullFormatter())
ax.bar_label(ax.containers[0], labels=df["Y"])
sns.despine()
plt.show()
PS: With these specific values, the plot might go without logscale:

sklearn random_state is not working properly

I read everything related to this but still did not understand what the problem is really. Basically I use TruncatedSVD with random_state and then print explained_variance_ratio_.sum() for it. It changes every time I run the code. Is this normal?
from sklearn.decomposition import TruncatedSVD
SVD = TruncatedSVD(n_components=40, n_iter=7, random_state=42)
XSVD = SVD.fit_transform(X)
print(SVD.explained_variance_ratio_.sum())
The problem is later I use umap and plot the result graph. And I have different graphs everytime I run the code. I do not understand if this is due to TruncatedSVD or UMAP. I use random_state=42 to stop things to change but it looks like there is no effect really.
You should probably do something wrong, because I cannot reproduce your issue with scikit-learn 0.22
In [16]: import numpy as np
...: from sklearn.decomposition import TruncatedSVD
...:
...: rng = np.random.RandomState(42)
...: X = rng.randn(10000, 100)
...: def func(X):
...: SVD = TruncatedSVD(n_components=40, n_iter=7, random_state=42)
...: XSVD = SVD.fit_transform(X)
...: print(SVD.explained_variance_ratio_.sum())
...: func(X);func(X);func(X);
0.43320350603512425
0.43320350603512425
0.43320350603512425

Labels in Plots

I am having some issues adding labels to the legend. For some reason matplotlib is ignoring the labels I create in the dataframe. Any help?
pandas version: 0.13.0
matplotlib version: 1.3.1
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
# Sample dataframe
d = {'date': [pd.to_datetime('1/1/2013'), pd.to_datetime('1/1/2014'), pd.to_datetime('1/1/2015')],
'number': [1,2,3],
'letter': ['A','B','C']}
df = pd.DataFrame(d)
####################
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(13, 10))
fig.subplots_adjust(hspace=2.0) ## Create space between plots
# Chart 1
df.plot(ax=axes[0], label='one')
# Chart 2
df.set_index('date')['number'].plot(ax=axes[1], label='two')
# add a little sugar
axes[0].set_title('This is the title')
axes[0].set_ylabel('the y axis')
axes[0].set_xlabel('the x axis')
axes[0].legend(loc='best')
axes[1].legend(loc='best');
The problem is that Chart 1 is returning the legend as "number" and I want it to say "one".
Will illustrate this for first axis. You may repeat for the second.
In [72]: fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(13, 10))
Get a reference to the axis
In [73]: ax=df.plot(ax=axes[0])
Get the legend
In [74]: legend = ax.get_legend()
Get the text of the legend
In [75]: text = legend.get_texts()[0]
Printing the current text of the legend
In [77]: text.get_text()
Out[77]: u'number'
Setting the desired text
In [78]: text.set_text("one")
Drawing to update
In [79]: plt.draw()
The following figure shows the changed legend for first axis. You may do the same for the other axis.
NB: IPython autocomplete helped a lot to figure out this answer!

using scalebar in matplotlib basemap

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
m = Basemap(projection='cyl',resolution='c',area_thresh=10,llcrnrlon=-180,urcrnrlon=180,\
llcrnrlat=-90,urcrnrlat=90)
m.etopo()
Actually, I did not know how to provide the lat, lon, lat0, and lon0 parameters required to show scale-bar. How to provide them?
map.drawmapscale(????,barstyle='simple',units='km',fontsize=9,labelstyle='simple',fontcolor='k')
The tutorial at
http://matplotlib.org/basemap/api/basemap_api.html describe it as follows:
drawmapscale(lon, lat, lon0, lat0, length, barstyle='simple', units='km', fontsize=9, yoffset=None, labelstyle='simple', fontcolor='k', fillcolor1='w', fillcolor2='k', ax=None, format='%d', zorder=None)
Would appreciate if someone could help me.
It appears that drawmapscale doesn't support Basemap instances with projection='cyl' (and possibly others; I have only checked projection='cyl' and projection='moll'):
In [7]: m = Basemap(projection='cyl',resolution='c',area_thresh=10,llcrnrlon=-180,\
urcrnrlon=180, llcrnrlat=-90,urcrnrlat=90)
In [8]: m.etopo()
Out[8]: <matplotlib.image.AxesImage at 0x10a899e90>
In [10]: m.drawmapscale(50, -75, 0, 0, 400)
This results in the following error:
ValueError: cannot draw map scale for projection='cyl'
But drawmapscale does appear to work for other projections. Using Mollweide, for example:
In [11]: m = Basemap(projection='moll', lon_0=0)
In [12]: m.etopo()
Out[12]: <matplotlib.image.AxesImage at 0x10c299450>
In [13]: m.drawmapscale(50, -75, 0, 0, 400)
Out[13]:
[<matplotlib.lines.Line2D at 0x11d2e41d0>,
<matplotlib.lines.Line2D at 0x109cd4d90>,
<matplotlib.lines.Line2D at 0x11d2e4750>,
<matplotlib.text.Text at 0x11d2e4d90>,
<matplotlib.text.Text at 0x11d2e5610>]
Unfortunately the Basemap API doesn't seem to mention anything about it not working for all projections. But here seems to be a potential workaround.