Function does not finish executing in `hist` function only on second time - python

In Python DataFrame, Im trying to generate histogram, it gets generated the first time when the function is called. However, when the create_histogram function is called second time it gets stuck at h = df.hist(bins=3, column="amount"). When I say "stuck", I mean to say that it does not finish executing the statement and the execution does not continue to the next line but at the same time it does not give any error or break out from the execution. What is exactly the problem here and how can I fix this?
import matplotlib.pyplot as plt
...
...
def create_histogram(self, field):
df = self.main_df # This is DataFrame
h = df.hist(bins=20, column="amount")
fileContent = StringIO()
plt.savefig(fileContent, dpi=None, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format="png",
transparent=False, bbox_inches=None, pad_inches=0.5,
frameon=None)
content = fileContent.getvalue()
return content

Finally I figured this out myself.
Whenever I executed the function I was always getting the following log message but I was ignoring it due to my lack of awareness.
Backend TkAgg is interactive backend. Turning interactive mode on.
But then I realised that may be its running in interactive mode (which was not my purpose). So, I found out that there is a way to turn it off, which is given below.
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
And this fixed my issue.
NOTE: the use should be called immediately after importing matplotlib in the sequence given here.

Related

Jupyter shows plot with and without plt.show() but with an addition of extra line [duplicate]

I have an array A of shape (1000, 2000). I use matplotlib.pyplot to plot the array, which means 1000 curves, using
import matplotlib.pyplot as plt
plt(A)
The figure is fine but there are a thousand lines of:
<matplotlib.lines.Line2D at 0xXXXXXXXX>
Can I disable this output?
This output is what the plt function is returning (I presume here you meant to write plt.plot(A)). To suppress this output assign the return object a name:
_ = plt.plot(A)
_ is often used to indicate a temporary object which is not going to be used later on. Note that this output you are seeing will only appear in the interpreter, and not when you run the script from outside the interpreter.
You can also suppress the output by use of ; at the end (assuming you are doing this in some sort of interactive environment)
plot(A);
plt.show()
This way there is no need to create unnecessary variables.
E.g.:
import matplotlib.pyplot as plt
plt.plot(A)
plt.show()
use a semi-colon after the plot command
eg:
plt.imshow(image,cmap);
will display the graph and stop the verbose
To ignore warnings
import warnings
warnings.filterwarnings("ignore")
This will resolve your issue.

Python script has to be run twice to execute

I have written a python script to gather and analyze data from a .csv file and then plot it using the matplotlib.pyplot module. I'm using numpy.genfromtext() to gather the data.
The first time I run the file, nothing happens. I get the console message:
>>> runfile('C:/my_filepath/thing.py')
and nothing more. If I run the file again, then it executes, prints the stuff, the plot comes up etc:
runfile('C:/my_filepath/thing.py')
~the stuff it's supposed to print~
More info: This problem only occurs on my laptop computer, which leads me to believe it has something to do with my matplotlib installation (mysterious to me because I installed an identical Anaconda package on my desktop and there is no issue). On the laptop the plot window is separate, and on the desktop the plot displays in the console. Maybe that's relevant.
Has anyone had this issue?
edit2: This only happens if I try to run the program multiple times in the same console. If I run the script in a fresh console it works fine, then you have to run it twice for every execution. If I close the matplotlib window, kill the console, and open a new one, I can execute it fine every time.
edit: here is a working example which exhibits the odd behavior. don't make fun of my code - I learned python over a weekend
import re
import numpy as np
from numpy import genfromtxt as gft
import matplotlib.pyplot as plt
def getnames(Pattern):
#construct the list of files in the directory
CSVList = []
for FileName in os.listdir():
if re.compile(Pattern).search(FileName):
CSVList.append(FileName)
print(len(CSVList), 'files found.')
#sort the list by the integer values of the last 4 digits of the filename
CSVList.sort(key=lambda x: int(x.rsplit('.')[0][-4:]))
return CSVList
def xy_extract(Data):
x = np.array([row[0] for row in Data])
y = np.array([row[1] for row in Data])
return x, y
CSVList = getnames('(?i)\.csv$')
print(CSVList)
#plt.figure(figsize=(10,5))
plt.xlim(799,3999)
for Filename in CSVList:
Data = gft(Filename, delimiter=',',skip_header=2)
x, y = xy_extract(Data)
plt.plot(x, y,label=Filename)
plt.show()

Pyplot "cannot connect to X server localhost:10.0" despite ioff() and matplotlib.use('Agg')

I have a piece of code which gets called by a different function, carries out some calculations for me and then plots the output to a file. Seeing as the whole script can take a while to run for larger datasets and since I may want to analyse multiple datasets at a given time I start it in screen then disconnect and close my putty session and check back on it the next day. I am using Ubuntu 14.04. My code looks as follows (I have skipped the calculations):
import shelve
import os, sys, time
import numpy
import timeit
import logging
import csv
import itertools
import graph_tool.all as gt
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.ioff()
#Do some calculations
print 'plotting indeg'
# Let's plot its in-degree distribution
in_hist = gt.vertex_hist(g, "in")
y = in_hist[0]
err = numpy.sqrt(in_hist[0])
err[err >= y] = y[err >= y] - 1e-2
plt.figure(figsize=(6,4))
plt.errorbar(in_hist[1][:-1], in_hist[0], fmt="o",
label="in")
plt.gca().set_yscale("log")
plt.gca().set_xscale("log")
plt.gca().set_ylim(0.8, 1e5)
plt.gca().set_xlim(0.8, 1e3)
plt.subplots_adjust(left=0.2, bottom=0.2)
plt.xlabel("$k_{in}$")
plt.ylabel("$NP(k_{in})$")
plt.tight_layout()
plt.savefig("in-deg-dist.png")
plt.close()
print 'plotting outdeg'
#Do some more stuff
The script runs perfectly happily until I get to the plotting commands. To try and get to the root of the problem I am currently running it in putty without screen and with no X11 applications. The ouput I get is the following:
plotting indeg
PuTTY X11 proxy: unable to connect to forwarded X server: Network error: Connection refused
: cannot connect to X server localhost:10.0
I presume this is caused by the code trying to open a window but I thought that by explicitely setting plt.off() that would be disabled. Since it wasn't I followed this thread (Generating matplotlib graphs without a running X server ) and specified the backend, but that didn't solve the problem either. Where might I be going wrong?
The calling function calls other functions too which also use matplotlib. These get called only after this one but during the import statement their dependecies get loaded. Seeing as they were loaded first they disabled the subsequent matplotlib.use('Agg') declaration. Moving that declaration to the main script has solved the problem.

IPython InteractiveShell fails to yield rich output when using `%matplotlib inline`

I am writing a custom client (a web-based graph representation of an IPython Notebook) for an IPython application and the easiest way to manage IPython programmatically seems to be using the IPython.core.InteractiveShell instance.
Consider this example: when a Jupyter Notebook cell that uses rich output is executed with inline magic, Notebook shows the appropriate rich representation (a plotted image) of plt.show() inline:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)
plt.plot(t, s)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.grid(True)
plt.show()
I want to be able to retrieve the image when using IPython programmatically via its API, namely InteractiveShell, like this:
from IPython.core.interactiveshell import InteractiveShell
shell = InteractiveShell()
result = shell.run_cell("...above code of the cell here...")
# result either gives an error when using %matplotlib inline or retrieves
# no useful info if no line magic is present
Problem is that InteractiveShell instance will not accept the %matplotlib inline magic, giving a NotImplementedError in its enable_gui method which is, wll, not implemented. I found very few information about this apart from a single issue on IPython's Github.
I know I can do this manually by using plt.save() but that doesn't seem right to me as I don't want to write manual interpretations each time I need another rich representation of the result. I feel like I'm missing a lot here in the way IPython works, so I'm asking for help in retrieving the results. What exactly does Jupyter Notebook do to retrieve the rich representation and perhaps can it be done painlessly via other means? I'm looking at using jupyter_client but for now that seems to be even more confusing.
UPDATE:
The io.capture_output context manager seems to be the way to go but I've been able to capture string outputs only (pretty much the same as using %%capture cell magic):
with io.capture_output() as captured:
result = shell.run_cell(cell)
#captures strings only:
captured.stdout = {str} '<matplotlib.figure.Figure at 0x4f486d8>'

Disable the output of matplotlib pyplot

I have an array A of shape (1000, 2000). I use matplotlib.pyplot to plot the array, which means 1000 curves, using
import matplotlib.pyplot as plt
plt(A)
The figure is fine but there are a thousand lines of:
<matplotlib.lines.Line2D at 0xXXXXXXXX>
Can I disable this output?
This output is what the plt function is returning (I presume here you meant to write plt.plot(A)). To suppress this output assign the return object a name:
_ = plt.plot(A)
_ is often used to indicate a temporary object which is not going to be used later on. Note that this output you are seeing will only appear in the interpreter, and not when you run the script from outside the interpreter.
You can also suppress the output by use of ; at the end (assuming you are doing this in some sort of interactive environment)
plot(A);
plt.show()
This way there is no need to create unnecessary variables.
E.g.:
import matplotlib.pyplot as plt
plt.plot(A)
plt.show()
use a semi-colon after the plot command
eg:
plt.imshow(image,cmap);
will display the graph and stop the verbose
To ignore warnings
import warnings
warnings.filterwarnings("ignore")
This will resolve your issue.

Categories

Resources