Annotating a box outside the box, matplotlib - matplotlib

I want the text to appear beside the box instead of inside it:
Here is what I did:
import matplotlib as mpl
import matplotlib.pyplot as plt
from custombox import MyStyle
fig = plt.figure(figsize=(10,10))
legend_ax = plt.subplot(111)
legend_ax.annotate("Text",xy=(0.5,0.5),xycoords='data',xytext=(0.5, 0.5),textcoords= ('data'),ha="center",rotation = 180,bbox=dict(boxstyle="angled, pad=0.5", fc='white', lw=4, ec='Black'))
legend_ax.text(0.6,0.5,"Text", ha="center",size=15)
Here is what it gives me:
Note: custombox is similar to the file that is written in this link:
http://matplotlib.org/1.3.1/users/annotations_guide.html
My ultimate aim is to make it look legend like where the symbol (angled box) appears beside the text that represents it.
EDIT 1: As suggested by Ajean I have annotated text separately but I can't turn of the text within the arrow

One way to do it would be to separate the text and the bbox (which you can reproduce using an arrow). The following gives me something close to what you want, I think.
import matplotlib.pyplot as plt
from matplotlib import patches
fig = plt.figure(figsize=(5,5))
ax = fig.add_subplot(111)
ax.annotate("Text", (0.4,0.5))
bb = patches.FancyArrow(0.5,0.5,0.1,0.0,length_includes_head=True, width=0.05,
head_length=0.03, head_width=0.05, fc='white', ec='black',
lw=4)
ax.add_artist(bb)
plt.show()
You can futz with the exact placement as needed. I'm not an expert on all the kwargs, so this may not be the best solution, but it will work.

Related

how to make plt plot do not show figure [duplicate]

I need to create a figure in a file without displaying it within IPython notebook. I am not clear on the interaction between IPython and matplotlib.pylab in this regard. But, when I call pylab.savefig("test.png") the current figure get's displayed in addition to being saved in test.png. When automating the creation of a large set of plot files, this is often undesirable. Or in the situation that an intermediate file for external processing by another app is desired.
Not sure if this is a matplotlib or IPython notebook question.
This is a matplotlib question, and you can get around this by using a backend that doesn't display to the user, e.g. 'Agg':
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('/tmp/test.png')
EDIT: If you don't want to lose the ability to display plots, turn off Interactive Mode, and only call plt.show() when you are ready to display the plots:
import matplotlib.pyplot as plt
# Turn interactive plotting off
plt.ioff()
# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)
# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')
# Display all "open" (non-closed) figures
plt.show()
We don't need to plt.ioff() or plt.show() (if we use %matplotlib inline). You can test above code without plt.ioff(). plt.close() has the essential role. Try this one:
%matplotlib inline
import pylab as plt
# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()
# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)
# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')
If you run this code in iPython, it will display a second plot, and if you add plt.close(fig2) to the end of it, you will see nothing.
In conclusion, if you close figure by plt.close(fig), it won't be displayed.

How to show legend in missingno matrix?

So far, I have managed to spawn a legend box and have managed to put it outside the chart. But it is showing the same colours for both the labels (white and white) whereas I would prefer it to show white and gray.
import missingno as msno
msno.matrix(X_train, figsize=(15,10), sparkline=False, p=0);
plt.legend(['missing','not missing'],loc='center left', bbox_to_anchor=(1, 0.5))
You'll have to craft the legend by hand. matplotlib has a legend guide showing how you can do this. The section describing "proxy artists" in particular is relevant to your use case. I haven't tested it, but the following should work:
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import missingno as msno
msno.matrix(...your data...)
gray_patch = mpatches.Patch(color='gray', label='Data present')
white_patch = mpatches.Patch(color='white', label='Data absent ')
plt.legend(handles=[gray_patch, white_patch])
plt.show()

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

How to disable the close button in matplotlib

I used matplotlib to create a graphics window, but I do not want the user to manually close it. Is there a way to disable the closing button in the upper right corner? See screenshot
The solution will depend on the backend in use.
PyQt
For the PyQt backend, you can do the following:
import matplotlib
# make sure Qt backend is used
matplotlib.use("Qt4Agg")
from PyQt4 import QtCore
import matplotlib.pyplot as plt
# create a figure and some subplots
fig, ax = plt.subplots(figsize=(4,2))
ax.plot([2,3,5,1])
fig.tight_layout()
win = plt.gcf().canvas.manager.window
win.setWindowFlags(win.windowFlags() | QtCore.Qt.CustomizeWindowHint)
win.setWindowFlags(win.windowFlags() & ~QtCore.Qt.WindowCloseButtonHint)
plt.show()
This will disable the close button (not hide it).
Tk
I'm not sure if Tk is able to control the close button. But what is possible is to draw a completely frameless window.
import matplotlib
# make sure Tk backend is used
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
# create a figure and some subplots
fig, ax = plt.subplots(figsize=(4,2))
ax.plot([2,3,5,1])
fig.tight_layout()
win = plt.gcf().canvas.manager.window
win.overrideredirect(1) # draws a completely frameless window
plt.show()

Calling pylab.savefig without display in ipython

I need to create a figure in a file without displaying it within IPython notebook. I am not clear on the interaction between IPython and matplotlib.pylab in this regard. But, when I call pylab.savefig("test.png") the current figure get's displayed in addition to being saved in test.png. When automating the creation of a large set of plot files, this is often undesirable. Or in the situation that an intermediate file for external processing by another app is desired.
Not sure if this is a matplotlib or IPython notebook question.
This is a matplotlib question, and you can get around this by using a backend that doesn't display to the user, e.g. 'Agg':
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('/tmp/test.png')
EDIT: If you don't want to lose the ability to display plots, turn off Interactive Mode, and only call plt.show() when you are ready to display the plots:
import matplotlib.pyplot as plt
# Turn interactive plotting off
plt.ioff()
# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)
# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')
# Display all "open" (non-closed) figures
plt.show()
We don't need to plt.ioff() or plt.show() (if we use %matplotlib inline). You can test above code without plt.ioff(). plt.close() has the essential role. Try this one:
%matplotlib inline
import pylab as plt
# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()
# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)
# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')
If you run this code in iPython, it will display a second plot, and if you add plt.close(fig2) to the end of it, you will see nothing.
In conclusion, if you close figure by plt.close(fig), it won't be displayed.