python pyplot legend adjust (location, size) - python

I am trying to change location of plot legend. Below what I've got for now.
var_list=powiaty_cols[powiaty_cols.str.contains("apart_bel_40")]
for var in var_list:
fig = plt.figure(figsize=(25, 25))
ax = plt.gca()
powiaty.plot(column=var,cmap='Reds', categorical=True,
legend=True, ax=ax,edgecolor='black')
ax.legend(loc='best')
This code is plotting figure but without legend. I've received errors as follows:
No handles with labels found to put in legend.
No handles with labels found to put in legend.
No handles with labels found to put in legend.
No handles with labels found to put in legend.
But without part 'ax.legend(loc='best')' I can get my plot but legend is in upper left corner. Plotted column is filled with integer from 1 to 5. Similar issue is when I'm trying to change size of legend.
Could maybe somebody help in this?

I don't know what powiaty is, but my guess is that you need to get the Axes object back so you can continue modifying it. Try:
ax = powiaty.plot(column=var, cmap='Reds', categorical=True,
legend=True, ax=ax, edgecolor='black'
)

For me worked:
leg = ax.get_legend()
leg.set_bbox_to_anchor((0., 0.1, 0.2, 0.2))

Related

Remove colorbar from map plot

I have a plot of a map containing areas which are color coded. I need to remove the automatic color bar from the plot and replace with a legend. However, I cannot find a way to remove the color bar. Xarray was used to create the data array.
map_crs = ccrs.OSGB()
fig = plt.figure(figsize=(10, 15))
cmap = mpl.colors.ListedColormap(colours)
norm = mpl.colors.BoundaryNorm(boundaries=bins, ncolors=len(cmap.colors)-1 )
stamen_terrain = cigmt.Stamen('terrain')
ax = plt.axes(projection=stamen_terrain.crs)
data_array.plot(transform=map_crs, vmin=0, vmax=np.max(data_array), cmap=cmap)
plt.gca().coastlines()
plt.tight_layout()
plt.savefig(plotname, bbox_inches="tight", pad_inches=0.1)
plt.clf()
I have tried adding commands such as, colorbar=False, cbar=False, Colorbar=False. However, just continually receive the corresponding error;
AttributeError: 'QuadMesh' object has no property 'Colorbar'
Any ideas on how to get rid of the colorbar?
Done!
Just needed to put add_colorbar=False into the plotting command.
Now to add the legend!

How to add a proper Legend in python matplotlib

classes=['1','-1']
colors = {1:'red',-1:'green'}
fig, axs = plt.subplots(1,1,figsize=(10,10))
axs.set_xlabel('X1')#Features
axs.set_ylabel('X2')#Features
axs.set_title('Scatter plot of Data Target VS Features')
plt.scatter(X[X.columns[0]],X[X.columns[1]],c=Y.map(colors),label=classes,cmap=Y.map(colors))
axs.grid(True)
legend1=axs.legend(['-1','1'],loc="lower left", title="CLass",frameon=False)
axs.add_artist(legend1)
plt.show()
Here above is my code to simply scatter a dataset and it was working well until it comes to Legend.
I want to set each class its related tag as Legend but I get the below result and it does not help with the red data:
As we can see we only have green data legend and not the red one:
I don't want to use for_loop or anything strange.
I've seen similar questions but can't figure out how to fix them.
Why not just
scatter_plot = plt.scatter(
X[X.columns[0]],
X[X.columns[1]],
c=Y.map(colors),
label=classes,
cmap=Y.map(colors)
)
plt.legend(
handles=scatter_plot.legend_elements()[0],
labels=classes,
loc="lower left",
title="Class"
)

Matplotlib "savefig" as pdf, text overlay

If i run this code in python:
titles = ctf01[0,1:]
fig = plt.figure(figsize=(11.69,8.27), dpi=100)
for num in range(len(titles)):
ax = fig.add_subplot(3,4,num+1)
ax.plot(ctf03[1:,num+1], ctf0102[:,num], 'ro')
ax.set_title(titles[num])
plt.tight_layout()
fig.text(0.5, 0.04, 'CTF12', ha='center')
fig.text(0.04, 0.5, 'CTF3', va='center', rotation='vertical')
fig.savefig("example.pdf")
i get this in the pdf file:
I would like to fix the problem with the "figure title" shown in the red circles.
If i set the 0.04 value as an negative value the title runs out of paper.
I also would like to save some space with moving the title of the subplots (green circles) into the diagram. Any idea how i can realize this?
Thanks for help.
try to add before fig.savefig("example.pdf") following line.
plt.tight_layout()
you have it in your script but it should come after text
It looks like you're trying to set the x and y labels for the whole figure, which isn't possible as these can only be set on an Axes object. Fortunately we can work around it by creating an 'invisible' subplot that fills the whole area and set the labels on this.
After plotting your subplots you would create the invisible one with:
label_ax = fig.add_subplot(111, frameon=False)
The frameon argument prevents it from drawing the box that is added by the default style. Then you tell it not to draw tick marks and make the tick labels invisible (we can't just remove them as it will mess up the spacing).
label_ax.tick_params(bottom=False, left=False, labelcolor="none")
Finally, set your labels:
label_ax.set_xlabel("CTF12")
label_ax.set_ylabel("CTF3")
You can adjust the vertical positioning of the plot titles by providing a pad argument to the set_title function. Giving a negative value will push the title into the plot, you'll need trial and error to find the value that works.
Putting it all together (with made-up data):
fig = plt.figure(figsize=(11.69, 8.27), dpi=100)
for i in range(10):
ax = fig.add_subplot(3, 4, i + 1)
ax.plot([1, 2, 3, 4, 5], "ro")
ax.set_title("Plot {}".format(i), pad=-15)
label_ax = fig.add_subplot(111, frameon=False)
label_ax.tick_params(bottom=False, left=False, labelcolor="none")
label_ax.grid(False) # In case the current style displays a grid.
label_ax.set_xlabel("CTF12")
label_ax.set_ylabel("CTF3")
fig.tight_layout()
fig.savefig("example.pdf")
Which gives:

Python - Remove borders from charts and legend

I have the following plot:
dfA.plot.bar(stacked=True, color=[colorDict.get(x, '#333333') for x in
dfA.columns],figsize=(10,8))
plt.legend(loc='upper right', bbox_to_anchor=(1.4, 1))
Which displays this:
I want to remove all of the borders of the chart and legend i.e. the box around the chart (leaving the axis numbers like 2015 and 6000 etc)
All of the examples I find refer to spines and 'ax', however I have not built my chart using fig = plt.figure() etc.
Anyone know how to do it?
You can remove the border of the legend by using the argument frameon=False in the call to plt.legend().
If you only have one figure and axes active, then you can use plt.gca() to get the current axes. Alternatively df.plot.bar returns an axes object (which I would suggest using because plt.gca() might get confusing when working with multiple figures). Therefore you can set the visibility of the spines to False:
ax = dfA.plot.bar(stacked=True, color=[colorDict.get(x, '#333333') for x in
dfA.columns],figsize=(10,8))
plt.legend(loc='upper right', bbox_to_anchor=(1.4, 1), frameon=False)
for spine in ax.spines:
ax.spines[spine].set_visible(False)
# Color of the spines can also be set to none, suggested in the comments by ScoutEU
# ax.spines[spine].set_color("None")

Hiding axis text in matplotlib plots

I'm trying to plot a figure without tickmarks or numbers on either of the axes (I use axes in the traditional sense, not the matplotlib nomenclature!). An issue I have come across is where matplotlib adjusts the x(y)ticklabels by subtracting a value N, then adds N at the end of the axis.
This may be vague, but the following simplified example highlights the issue, with '6.18' being the offending value of N:
import matplotlib.pyplot as plt
import random
prefix = 6.18
rx = [prefix+(0.001*random.random()) for i in arange(100)]
ry = [prefix+(0.001*random.random()) for i in arange(100)]
plt.plot(rx,ry,'ko')
frame1 = plt.gca()
for xlabel_i in frame1.axes.get_xticklabels():
xlabel_i.set_visible(False)
xlabel_i.set_fontsize(0.0)
for xlabel_i in frame1.axes.get_yticklabels():
xlabel_i.set_fontsize(0.0)
xlabel_i.set_visible(False)
for tick in frame1.axes.get_xticklines():
tick.set_visible(False)
for tick in frame1.axes.get_yticklines():
tick.set_visible(False)
plt.show()
The three things I would like to know are:
How to turn off this behaviour in the first place (although in most cases it is useful, it is not always!) I have looked through matplotlib.axis.XAxis and cannot find anything appropriate
How can I make N disappear (i.e. X.set_visible(False))
Is there a better way to do the above anyway? My final plot would be 4x4 subplots in a figure, if that is relevant.
Instead of hiding each element, you can hide the whole axis:
frame1.axes.get_xaxis().set_visible(False)
frame1.axes.get_yaxis().set_visible(False)
Or, you can set the ticks to an empty list:
frame1.axes.get_xaxis().set_ticks([])
frame1.axes.get_yaxis().set_ticks([])
In this second option, you can still use plt.xlabel() and plt.ylabel() to add labels to the axes.
If you want to hide just the axis text keeping the grid lines:
frame1 = plt.gca()
frame1.axes.xaxis.set_ticklabels([])
frame1.axes.yaxis.set_ticklabels([])
Doing set_visible(False) or set_ticks([]) will also hide the grid lines.
If you are like me and don't always retrieve the axes, ax, when plotting the figure, then a simple solution would be to do
plt.xticks([])
plt.yticks([])
I've colour coded this figure to ease the process.
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
You can have full control over the figure using these commands, to complete the answer I've add also the control over the spines:
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# X AXIS -BORDER
ax.spines['bottom'].set_visible(False)
# BLUE
ax.set_xticklabels([])
# RED
ax.set_xticks([])
# RED AND BLUE TOGETHER
ax.axes.get_xaxis().set_visible(False)
# Y AXIS -BORDER
ax.spines['left'].set_visible(False)
# YELLOW
ax.set_yticklabels([])
# GREEN
ax.set_yticks([])
# YELLOW AND GREEN TOGHETHER
ax.axes.get_yaxis().set_visible(False)
I was not actually able to render an image without borders or axis data based on any of the code snippets here (even the one accepted at the answer). After digging through some API documentation, I landed on this code to render my image
plt.axis('off')
plt.tick_params(axis='both', left=False, top=False, right=False, bottom=False, labelleft=False, labeltop=False, labelright=False, labelbottom=False)
plt.savefig('foo.png', dpi=100, bbox_inches='tight', pad_inches=0.0)
I used the tick_params call to basically shut down any extra information that might be rendered and I have a perfect graph in my output file.
Somewhat of an old thread but, this seems to be a faster method using the latest version of matplotlib:
set the major formatter for the x-axis
ax.xaxis.set_major_formatter(plt.NullFormatter())
One trick could be setting the color of tick labels as white to hide it!
plt.xticks(color='w')
plt.yticks(color='w')
or to be more generalized (#Armin Okić), you can set it as "None".
When using the object oriented API, the Axes object has two useful methods for removing the axis text, set_xticklabels() and set_xticks().
Say you create a plot using
fig, ax = plt.subplots(1)
ax.plot(x, y)
If you simply want to remove the tick labels, you could use
ax.set_xticklabels([])
or to remove the ticks completely, you could use
ax.set_xticks([])
These methods are useful for specifying exactly where you want the ticks and how you want them labeled. Passing an empty list results in no ticks, or no labels, respectively.
You could simply set xlabel to None, straight in your axis. Below an working example using seaborn
from matplotlib import pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
ax = sns.boxplot(x="day", y="total_bill", data=tips)
ax.set(xlabel=None)
plt.show()
Just do this in case you have subplots
fig, axs = plt.subplots(1, 2, figsize=(16, 8))
ax[0].set_yticklabels([]) # x-axis
ax[0].set_xticklabels([]) # y-axis

Categories

Resources