Zoom not working on Loading pickled matplotlib Figure - matplotlib

I want to store a matplotlib figure and load it later to use it interactively. To be more specific, I want to be able to use zoom in this figure.
I am using pickle to dump the figure handle into a file.
I then load the figure later using pickle, but the zoom does not work after loading the file even though I can use zoom in the figure before pickling it.
Here's a sample script that illustrates my problem.
import matplotlib.pyplot as plt
import pickle
import numpy as np
import os
import time
# Create Plot Data
x = np.arange(100)
# Create Figure, Axes and plot
fig1,axes1 = plt.subplots()
axes1.plot(x)
# Pickle plot
fileName = os.getcwd() + "/img"\
+ time.asctime(time.localtime()) + ".pickle"
with open(fileName,'wb') as pickle_file:
pickle.dump(fig1,pickle_file)
plt.show() # ZOOM WORKS HERE
plt.close()
# Load pickled plot
with open(fileName,'rb') as read_pickle:
fig_handle = pickle.load(read_pickle)
plt.show() # ZOOM DOES NOT WORK HERE
Zooming into the image before Pickle
Non-Zoomable image after Pickle
Version:
Python 3.7.0
Matplotlib 3.0.0
Pickle 4.0
Is this a limitation with Pickling matplotlib figure? Or is there something I can do to load/dump the figure in a zoomable way?

As #ImportanceOfBeingErnest pointed out I fixed the problem by changing my backends from MacOSX to TkAgg.
Here's what I did.
import matplotlib
matplotlib.get_backend() # Get the current backend
'MacOSX'
# Get Location where configuration file was loaded from.
matplotlib.matplotlib_fname()
'/usr/local/lib/python3.7/site-packages/matplotlib/mpl-data/matplotlibrc'
# Edit -> backend:TkAgg
matplotlib.get_backend()
'TkAgg'

Related

Unable to generate plot using matplotlib

I am a beginner to Python and experimenting with a plot. the script runs fine but plot does not show up.
the matplotlib and numpy libraries are installed.
import numpy as np
f= h5py.File('3DIMG_05JUN2021_0000_L3B_HEM_DLY.h5','r')
#Studying the structure of the file by printing what HDF5 groups are present
for key in f.keys():
print(key) #Names of the groups in HDF5 file.
# will print the variables in the file
#Get the HDF5 group
ls=list(f.keys())
print("ls")
print(ls)
tsurf = f['HEM_DLY'][:]
print("tsurf")
print(tsurf)
tsurf1=np.squeeze(tsurf)
print(tsurf1.shape)
import matplotlib.pyplot as plt
im= plt.plot(tsurf1)
#plt.colorbar()
plt.imshow(im)```
Python version is 3 running on Ubuntu
Difficult to give you the exact answer without the dataset (please update the question with the dataset), but for sure, plt.plot does not return an object that can be plotted with plt.imshow
Try instead:
ax = plt.plot(tsurf1)
plt.show()
Probably the error was on the final plot.Try this:
import numpy as np
import matplotlib.pyplot as plt
f= h5py.File('/path','r')
ls=list(f.keys())
tsurf = f['your_key_str'][:]
tsurf1=np.squeeze(tsurf)
im= plt.plot(tsurf1)
plt.show(im) # <-- plt.show() NOT plt.imshow()

Matplotlib graph does not show in Python Interactive Window

The following is my code, but I can't get the plot to show on my Visual Studio Code even though I am running this on the Python Interactive Window, which should usually show a graph plot after running. The tables are showing just fine. I also do not get a default graph which pops up like it normally should. What am I doing wrong?
import yfinance as yf
import pandas as pd
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import talib
df = pd.read_csv('filename.csv')
df = df.sort_index()
macd, macdsignal, macdhist = talib.MACD(df['Close'], fastperiod=12, slowperiod=26, signalperiod=9)
macd = macd.to_list()
macdsignal = macdsignal.to_list()
macdhist = macdhist.to_list()
df['macd'], df['macdsignal'], df['macdhist'] = macd,macdsignal,macdhist
ax = plt.gca()
print(df.columns)
df.plot(kind='line',x='Date',y='macd', color='blue',ax=ax)
df.plot(kind='line',x='Date',y='macdsignal', color='red', ax=ax)
plt.show()
The csv file has data that looks like this
The issue was with matplotlib.use('agg'), which does not support the show() function. This prevented the graph from being displayed on Visual Studio's Interactive Window. The matplotlib.use('agg') method can, however, be used for saving your graph in a .png format.
According to Matplotlib.org, agg is "the canonical renderer for user interfaces, which uses the Anti-Grain Geometry C++ library to make a raster (pixel) image of the figure". More information can be found at this link here

Saving Matplotlib Output to DBFS on Databricks

I'm writing Python code on Databricks to process some data and output graphs. I want to be able to save these graphs as a picture file (.png or something, the format doesn't really matter) to DBFS.
Code:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'fruits':['apple','banana'], 'count': [1,2]})
plt.close()
df.set_index('fruits',inplace = True)
df.plot.bar()
# plt.show()
Things that I tried:
plt.savefig("/FileStore/my-file.png")
[Errno 2] No such file or directory: '/FileStore/my-file.png'
fig = plt.gcf()
dbutils.fs.put("/dbfs/FileStore/my-file.png", fig)
TypeError: has the wrong type - (,) is expected.
After some research, I think the fs.put only works if you want to save text files.
running the above code with plt.show() will get you a bar graph - I want to be able to save the bar graph as an image to DBFS. Any help is appreciated, thanks in advance!
Easier way, just with matplotlib.pyplot. Fix the dbfs path:
Example
import matplotlib.pyplot as plt
plt.scatter(x=[1,2,3], y=[2,4,3])
plt.savefig('/dbfs/FileStore/figure.png')
You can do this by saving the figure to memory and then using the Python local file APIs to write to the DataBricks filesystem (DBFS).
Example:
import matplotlib.pyplot as plt
from io import BytesIO
# Create a plt or fig, then:
buf = BytesIO()
plt.savefig(buf, format='png')
path = '/dbfs/databricks/path/to/file.png'
# Make sure to open the file in bytes mode
with open(path, 'wb') as f:
# You can also use Bytes.IO.seek(0) then BytesIO.read()
f.write(buf.getvalue())

Graphing matplotlib with Python code in a R Markdown document

Is it possible to use Python matplotlib code to draw graph in RStudio?
e.g. below Python matplotlib code:
import numpy as np
import matplotlib.pyplot as plt
n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)
plt.plot (X, Y+1, color='blue', alpha=1.00)
plt.plot (X, Y-1, color='blue', alpha=1.00)
plt.show()
Output graph will be:
Then I need to write a R Markdown to include these code and generate graph automatically after knitting the markdown.
install.packages('devtools') first, get install_github function
install_github("rstudio/reticulate") install the dev version of reticulate
in r markdown doc, use code below to enable the function.
```{r setup, include=FALSE}
library(knitr)
library(reticulate)
knitr::knit_engines$set(python = reticulate::eng_python)
```
Try it , you will get what you want and don't need to save any image.
One possible solution is save the plot as a image, then load the file to markdown.
### Call python code sample
```{r,engine='python'}
import numpy as np
import matplotlib.pyplot as plt
n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)
fig, ax = plt.subplots( nrows=1, ncols=1 )
ax.plot (X, Y+1, color='blue', alpha=1.00)
ax.plot (X, Y-1, color='blue', alpha=1.00)
#plt.show()
fig.savefig('foo.png', bbox_inches='tight')
print "finished"
```
Output image:
![output](foo.png)
#### The End
Output:
You can do that with reticulate, but most time in trying to follow a tutorial in doing that you may encounter some technicalities that weren't sufficiently explained.
My answer is a little late but I hope it's a thorough walkthrough of doing it the right way - not rendering it and then loading it as a png but have the python code executed more "natively".
Step 1: Configure Python from RStudio
You want to insert an R chunk, and run the following code to configure the path to the version of Python you want to use. The default python that comes shipped with most OS is usually the outdated python 2 and is not where you install your packages. That is the reason why it's important to do this, to make sure Rstudio will use the specified python instance where your matplotlib library (and the other libraries you will be using for that project) can be found:
library(reticulate)
# change the following to point to the desired path on your system
use_python('/Users/Samuel/anaconda3/bin/python')
# prints the python configuration
py_config()
You should expect to see that your session is configured with the settings you specified:
python: /Users/Samuel/anaconda3/bin/python
libpython: /Users/Samuel/anaconda3/lib/libpython3.6m.dylib
pythonhome: /Users/Samuel/anaconda3:/Users/Samuel/anaconda3
version: 3.6.3 |Anaconda custom (64-bit)| (default, Oct 6 2017, 12:04:38) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
numpy: /Users/Samuel/anaconda3/lib/python3.6/site-packages/numpy
numpy_version: 1.15.2
python versions found:
/Users/Samuel/anaconda3/bin/python
/usr/bin/python
/usr/local/bin/python
/usr/local/bin/python3
/Users/Samuel/.virtualenvs/r-tensorflow/bin/python
Step 2: The familiar plt.show
Add a Python chunk (not R!) in your R Markdown document (see attached screenshot) and you can now write native Python code. This means that the familiar plt.show() and plt.imshow() will work without any extra work. It will be rendered and can be compiled into HTML / PDF using knitr.
This will work:
plt.imshow(my_image, cmap='gray')
Or a more elaborated example:
import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
DATADIR = '/Users/Samuel/Datasets/PetImages'
CATEGORIES = ['Dog', 'Cat']
for category in CATEGORIES:
path = os.path.join(DATADIR, category) # path to cat or dog dir
for img in os.listdir(path):
img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)
plt.imshow(img_array, cmap='gray')
plt.show()
break
break
Output:
Step 3: Knit to HTML / PDF / Word etc
Proceed to knit as usual. The end product is a beautifully formatted document done in Python code using R Markdown. RStudio has come a long way and I'm surprised the level of support it has for Python code isn't more known so hoping anyone that stumbled upon this answer will find it informative and learned something new.
I have been working with reticulate and R Markdown and you should specify your virtual environment. For example my R Markdown starts as follows:
{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, cache.lazy = FALSE)
library(reticulate)
use_condaenv('pytorch') ## yes, you can run pytorch and tensor flow too
Then you can work in either language. So, for plotting with matplotlib, I have found that you need the PyQt5 module to make it all run smoothly. The following makes a nice plot inside R Markdown - it's a separate chunk.
{python plot}
import PyQt5
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
data = pd.read_csv('Subscriptions.csv',index_col='Date', parse_dates=True)
# make the nice plot
# set the figure size
fig = plt.figure(figsize = (15,10))
# the series
ax1 = fig.add_subplot(211)
ax1.plot(data.index.values, data.Opens, color = 'green', label = 'Opens')
# plot the legend for the first plot
ax1.legend(loc = 'upper right', fontsize = 14)
plt.ylabel('Opens', fontsize=16)
# Hide the top x axis
ax1.axes.get_xaxis().set_visible(False)
####### NOW PLOT THE OTHER SERIES ON A SINGLE PLOT
# plot 212 is the MI series
# plot series
ax2 = fig.add_subplot(212)
ax2.plot(data.index.values, data.Joiners, color = 'orange', label = 'Joiners')
# plot the legend for the second plot
ax2.legend(loc = 'upper right', fontsize = 14)
# set the fontsize for the bottom plot
plt.ylabel('Joiners', fontsize=16)
plt.tight_layout()
plt.show()
You get the following from this:
I don't have the reputation points to add a comment, but Bryan's answer above was the only one to work for me. Adding plt.tight_layout() made the difference. I added that line to the following simple code and the plot displayed.
{python evaluate}
plt.scatter(X_train, y_train, color = 'gray')
plt.plot(X_train, regresssion_model_sklearn.predict(X_train), color = 'red')
plt.ylabel('Salary')
plt.xlabel('Number of Years of Experience')
plt.title('Salary vs. Years of Experience')
plt.tight_layout()
plt.show()

How to plot remote image (from http url)

This must be easy, but I can't figure how right now without using urllib module and manually fetching remote file
I want to overlay plot with remote image (let's say "http://matplotlib.sourceforge.net/_static/logo2.png"), and neither imshow() nor imread() can load the image.
Any ideas which function will allow loading remote image?
It is easy indeed:
import urllib2
import matplotlib.pyplot as plt
# create a file-like object from the url
f = urllib2.urlopen("http://matplotlib.sourceforge.net/_static/logo2.png")
# read the image file in a numpy array
a = plt.imread(f)
plt.imshow(a)
plt.show()
This works for me in a notebook with python 3.5:
from skimage import io
import matplotlib.pyplot as plt
image = io.imread(url)
plt.imshow(image)
plt.show()
you can do it with this code;
from matplotlib import pyplot as plt
a = plt.imread("http://matplotlib.sourceforge.net/_static/logo2.png")
plt.imshow(a)
plt.show()
pyplot.imread for URLs is deprecated
Passing a URL is deprecated. Please open the URL for reading and pass
the result to Pillow, e.g. with
np.array(PIL.Image.open(urllib.request.urlopen(url))).
Matplotlib suggests using PIL instead. I prefer using imageio as sugested by SciPy:
imread is deprecated in SciPy 1.0.0, and will be removed in 1.2.0. Use
imageio.imread instead.
imageio.imread(uri, format=None, **kwargs)
Reads an image from the specified file. Returns a numpy array, which
comes with a dict of meta data at its ‘meta’ attribute.
Note that the image data is returned as-is, and may not always have a
dtype of uint8 (and thus may differ from what e.g. PIL returns).
Example:
import matplotlib.pyplot as plt
from imageio import imread
url = "http://matplotlib.sourceforge.net/_static/logo2.png"
img = imread(url)
plt.imshow(img)