How to plot the whole point circle above axis line in matplotlib - matplotlib

Normally when you plot a list of points and axis. Only a part of point will be shown for those intersecting with the axis line, see the first point in this png for an example. How to make sure the whole point circle in shown above the axis line?

You can turn off the clipping by using the parameter clip_on of the plotting functions:
plt.plot(range(10), marker='o', ms=20, clip_on=False)

You can turn off clipping for the resulting plot artist(s) by setting clip_on=False in your call to plot or scatter. Note that you can also modify the clipping box by hand if you have a reference to the artist.
import matplotlib.pyplot as plt
plt.plot([0,1,2], [0,1,2], 'bo', clip_on=False)
produces:

Related

How to fix lines of axes overlapping imshow plot?

When plotting matrices using matplotlib's imshow function the lines of the axes can overlap the actual plot, see the following minimal example (matshow is just a simple wrapper around imshow):
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3,3))
ax.matshow(np.random.random((50, 50)), interpolation="none", cmap="Blues")
plt.savefig("example.png", dpi=300)
I would expect every entry of the matrix to be represented by a square, but in the top row it is quite obvious that the axis is hiding a bit of the plot resulting in non-square entries. The same is happening for the last column. Since I want the complete matrix to be seen - every entry with the same importance - is there any way this can be fixed?
To me, this is just a visualisation issue. If I run your code and maximise the window, I do not see the overlapping you are talking about:
Otherwise, remove the spines but without hiding the ticks:
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
EDIT
Reduce the thickness of the borders:
[x.set_linewidth(0.3) for x in ax.spines.values()]
The following is the exported image:
With 0.2 the exported image looks like this:

Scatter plot without x-axis

I am trying to visualize some data and have built a scatter plot with this code -
sns.regplot(y="Calls", x="clientid", data=Drop)
This is the output -
I don't want it to consider the x-axis. I just want to see how the data lie w.r.t y-axis. Is there a way to do that?
As #iayork suggested, you can see the distribution of your points with a striplot or a swarmplot (you could also combine them with a violinplot). If you need to move the points closer to the y-axis, you can simply adjust the size of the figure so that the width is small compared to the height (here i'm doing 2 subplots on a 4x5 in figure, which means that each plot is roughly 2x5 in).
fig, (ax1,ax2) = plt.subplots(1,2, figsize=(4,5))
sns.stripplot(d, orient='vert', ax=ax1)
sns.swarmplot(d, orient='vert', ax=ax2)
plt.tight_layout()
However, I'm going to suggest that maybe you want to use distplot instead. This function is specifically created to show the distribution of you data. Here i'm plotting the KDE of the data, as well as the "rugplot", which shows the position of the points along the y-axis:
fig = plt.figure()
sns.distplot(d, kde=True, vertical=True, rug=True, hist=False, kde_kws=dict(shade=True), rug_kws=dict(lw=2, color='orange'))

How to overlay one pyplot figure on another

Searching easily reveals how to plot multiple charts on one figure, whether using the same plotting axes, a second y axis or subplots. Much harder to uncover is how to overlay one figure onto another, something like this:
That image was prepared using a bitmap editor to overlay the images. I have no difficulty creating the individual plots, but cannot figure out how to combine them. I expect a single line of code will suffice, but what is it? Here is how I imagine it:
bigFig = plt.figure(1, figsize=[5,25])
...
ltlFig = plt.figure(2)
...
bigFig.overlay(ltlFig, pos=[x,y], size=[1,1])
I've established that I can use figure.add_axes, but it is quite challenging getting the position of the overlaid plot correct, since the parameters are fractions, not x,y values from the first plot. It also [it seems to me - am I wrong?] places constraints on the order in which the charts are plotted, since the main plot must be completed before the other plots are added in turn.
What is the pyplot method that achieves this?
To create an inset axes you may use mpl_toolkits.axes_grid1.inset_locator.inset_axes.
Position of inset axes in axes coordinates
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, ax= plt.subplots()
inset_axes = inset_axes(ax,
width=1, # inch
height=1, # inch
bbox_transform=ax.transAxes, # relative axes coordinates
bbox_to_anchor=(0.5,0.5), # relative axes coordinates
loc=3) # loc=lower left corner
ax.axis([0,500,-.1,.1])
plt.show()
Position of inset axes in data coordinates
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, ax= plt.subplots()
inset_axes = inset_axes(ax,
width=1, # inch
height=1, # inch
bbox_transform=ax.transData, # data coordinates
bbox_to_anchor=(250,0.0), # data coordinates
loc=3) # loc=lower left corner
ax.axis([0,500,-.1,.1])
plt.show()
Both of the above produce the same plot
(For a possible drawback of this solution see specific location for inset axes)

Clearing a subplot in Matplotlib

I have a number of subplots in a figure fig1, created via
ax = fig1.add_subplot(221)
I then plot stuff in each of the subplots via
im=ax.plot(x,y)
and add some axis labels via
ax.set_xlabel('xlabel')
I would then like to clear a specific subplot completely, as described in When to use cla(), clf() or close() for clearing a plot in matplotlib?. However the problem is that ax.cla()and ax.clear() seem to only clear the data from the plot, without removing the axes, axis tick labels etc. On the other hand plt.clf() clears the entire figure. Is there something in between? A clf-like command that clears everything in a subplot, including axis labels? Or have I simply used the commands in a wrong way?
ax.clear() clears the axes. That is, it removes all settings and data from the axes such that you are left with an axes, just as it had been just created.
ax.axis("off") turns the axes off, such that all axes spines and ticklabels are hidden.
ax.set_visible(False) turns the complete axes invisible, including the data that is in it.
ax.remove() removes the axes from the figure.
Complete example:
import matplotlib.pyplot as plt
fig,axes = plt.subplots(2,3)
for ax in axes.flat:
ax.plot([2,3,1])
axes[0,1].clear()
axes[1,0].axis("off")
axes[1,1].set_visible(False)
axes[0,2].remove()
plt.show()

Relocating legend from GeoPandas plot

I'm plotting a map with legends using the GeoPandas plotting function. When I plot, my legends appear in the upper right corner of the figure. Here is how it looks like:
I wanted to move the legends to the lower part of the graph. I would normally would have done something like this for a normal matplotlib plot:
fig, ax = plt.subplots(1, figsize=(4.5,10))
lima_bank_num.plot(ax=ax, column='quant_cuts', cmap='Blues', alpha=1, legend=True)
ax.legend(loc='lower left')
However, this modification is not taken into account.
This could be done using the legend_kwds argument:
df.plot(column='values', legend=True, legend_kwds={'loc': 'lower right'});
You can access the legend defined on the ax instance with ax.get_legend(). You can then update the location of the legend using the method set_bbox_to_anchor. This doesn't provide the same ease of use as the loc keyword when creating a legend from scratch, but does give control over placement. So, for your example, something like:
leg = ax.get_legend()
leg.set_bbox_to_anchor((0., 0., 0.2, 0.2))
A bit of documentation of set_bbox_to_anchor, though I don't find it extraordinarily helpful.
If you have a horizontal legend and you're trying to simply reduce the gap between the legend and plot, I recommend the colorbar approach detailed at https://gis.stackexchange.com/a/330175/32531 along with passing the pad legend_kwd argument:
legend_kwds={"orientation": "horizontal", "pad": 0.01}