Jupyter notebook matplotlib figures missing in exported pdf - matplotlib

When generating a pdf in jupyter notebook, everything works great, but I would like to keep the inline figures inside the pdf, as well as the notebook.
Here is my code:
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('png', 'pdf')
save_figures = True
x = np.arange(0, 20, 0.1)
y = np.sin(x)
plt.figure()
plt.plot(x, y)
if save_figures:
plt.savefig('test.png')
plt.show()
The figures appear inline, but in the pdf what is printed instead is:
<IPython.core.display.Javascript object>
<IPython.core.display.HTML object>
The same thing appears in the pdf if I export from the web or use nbconvert to export to pdf from the command line.
Are there any additional commands that I need to invoke in order to get this to work?

If you change the %matplotlib notebook to %matplotlib inline, then PDF export with jupyter's nbconvert works fine for me. The %matplotlib notebook magic renders the plot in an interactive way that I suspect isn't properly recognized by LaTeX, which is used during the PDF conversion.
Alternatively, if you have to use %matplotlib notebook for some reason, the export to HTML with jupyter's nbconvert (jupyter nbconvert --to='html' Test.ipynb) seems to preserve the plot. I am then able to print this HTML file to a PDF from a web browser and the plot is present in the final PDF.

Crude solution to interactive problem:
in interactive function save figure to a file
fig.savefig("pieCharts.png")
in next cell display a file:
from IPython.display import Image
Image("pieCharts.png")
In PDF only output of the 2nd line will be displayed with image as changed in interactive function.

Related

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

JupyterLab fig does not show. It shows blank result (but works fine on jupyternotebook)

I am new to JupyterLab trying to learn.
When I try to plot a graph, it works fine on jupyter notebook, but does not show the result on jupyterlab. Can anyone help me with this?
Here are the codes below:
import pandas as pd
import pandas_datareader.data as web
import time
# import matplotlib.pyplot as plt
import datetime as dt
import plotly.graph_objects as go
import numpy as np
from matplotlib import style
# from matplotlib.widgets import EllipseSelector
from alpha_vantage.timeseries import TimeSeries
Here is the code for plotting below:
def candlestick(df):
fig = go.Figure(data = [go.Candlestick(x = df["Date"], open = df["Open"], high = df["High"], low = df["Low"], close = df["Close"])])
fig.show()
JupyterLab Result:
Link to the image (JupyterLab)
JupyterNotebook Result:
Link to the image (Jupyter Notebook)
I have updated both JupyterLab and Notebook to the latest version. I do not know what is causing JupyterLab to stop showing the figure.
Thank you for reading my post. Help would be greatly appreciated.
Note*
I did not include the parts for data reading (Stock OHLC values). It contains the API keys. I am sorry for inconvenience.
Also, this is my second post on stack overflow. If this is not a well-written post, I am sorry. I will try to put more effort if it is possible. Thank you again for help.
TL;DR:
run the following and then restart your jupyter lab
jupyter labextension install #jupyterlab/plotly-extension
Start the lab with:
jupyter lab
Test with the following code:
import plotly.graph_objects as go
from alpha_vantage.timeseries import TimeSeries
def candlestick(df):
fig = go.Figure(data = [go.Candlestick(x = df.index, open = df["1. open"], high = df["2. high"], low = df["3. low"], close = df["4. close"])])
fig.show()
# preferable to save your key as an environment variable....
key = # key here
ts = TimeSeries(key = key, output_format = "pandas")
data_av_hist, meta_data_av_hist = ts.get_daily('AAPL')
candlestick(data_av_hist)
Note: Depending on system and installation of JupyterLab versus bare Jupyter, jlab may work instead of jupyter
Longer explanation:
Since this issue is with plotly and not matplotlib, you do NOT have to use the "inline magic" of:
%matplotlib inline
Each extension has to be installed to the jupyter lab, you can see the list with:
jupyter labextension list
For a more verbose explanation on another extension, please see related issue:
jupyterlab interactive plot
Patrick Collins already gave the correct answer.
However, the current JupyterLab might not be supported by the extension, and for various reasons one might not be able to update the JupyterLab:
ValueError: The extension "#jupyterlab/plotly-extension" does not yet support the current version of JupyterLab.
In this condition a quick workaround would be to save the image and show it again:
from IPython.display import Image
fig.write_image("image.png")
Image(filename='image.png')
To get the write_image() method of Plotly to work, kaleido must be installed:
pip install -U kaleido
This is a full example (originally from Plotly) to test this workaround:
import os
import pandas as pd
import plotly.express as px
from IPython.display import Image
df = pd.DataFrame([
dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28', Resource="Alex"),
dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15', Resource="Alex"),
dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30', Resource="Max")
])
fig = px.timeline(df, x_start="Start", x_end="Finish", y="Resource", color="Resource")
if not os.path.exists("images"):
os.mkdir("images")
fig.write_image("images/fig1.png")
Image(filename='images/fig1.png')

Matplotlib: emoji font does not work when using backend_pdf

I want to use the emoji-font "Symbola.ttf" to label my plots. This does work when I use plt.show(). But it does not work when using the backend_pdf. Only two emojis are shown in a mixed up order.
example images:
when using plt.show():
when using the backend_pdf:
example code:
Here is my code to produce these examples:
import matplotlib.backends.backend_pdf
import matplotlib.pyplot as plt
import emoji
from matplotlib.font_manager import FontProperties
emojis = [emoji.EMOJI_UNICODE[e] for e in list(emoji.EMOJI_UNICODE.keys())[620:630]]
prop = FontProperties(fname='./Symbola.ttf', size=30)
# backend_pdf plot
pdf = matplotlib.backends.backend_pdf.PdfPages("output.pdf")
plt.xticks(range(len(emojis)), emojis, fontproperties=prop)
pdf.savefig()
pdf.close()
# plt.show() plot
plt.xticks(range(len(emojis)), emojis, fontproperties=prop)
plt.show()
I'm running this on a Linux machine.
I think I have found the problem. It seems that my Symbola.ttf was broken. When I use this .ttf file everything works great.

Importing .py converted ipython notebook without changing pylab syntax

In an Ipython notebook, I have defined a function to plot data. I would like to import the function in my current notebook to use it.
I tried to convert the mynotebook.ipynb to a mynotebook.py file and then just do
from mynotebook import myfunction
But I get an error.
The problem is that I wrote the original notebook with starting ipython with the option pylab.
That means that to make it work, instead of writing something like
x = arange(1,10)
y = arange(1,10)
scatter(x, y)
I should change it to the more explicit:
import numpy as np
import matplotlib as plt
x = np.arange(1,10)
y = np.arange(1,10)
plt.scatter(x, y)
In my case my file is quite complex and changing it will be a pain...
Is there a way to import my notebook without modifying the .py file line by line???
from matplotlib.pylab import *
will take care of all of your imports, but some of the interactive stuff (show etc) might not work correctly.

ipython notebook pylab inline - matplotlib.pyplot - how to display plot with scrollbar?

I am using ipython notebook with pylab --inline
import matplotlib.pyplot as plt
import pandas as pd
......
plt.figsize(14,8)
ax1=plt.subplot(311)
#data is a pandas data frame with timeseries stock data
# this plots the data
data.plot(ax=ax1)
This shows a plot of the stock data but its all displayed at once.
I would like to display just subrange of dates and have a scrollbar to control what range
How do I do it such that it works with the inline display of plots.
You can't. Inline display is a static PNG.
If you want something like that you will have to use a Javascript plotting library for now.
None that I know of will work out of the box with panda.
You can't manipulate plots in inline-mode after they have been drawn. However, you can scale,zoom and resize plots in the interactive mode. Just start your notebook without the inline-option and all plots will be generated in an extra window with the functionality you asked for:
ipython notebook --pylab