So I need to make this plot in python. I wish to remove my legend's border. However, when I tried the different solutions other posters made, they were unable to work with mine. Please help.
This doesn't work:
plt.legend({'z$\sim$0.35', 'z$\sim$0.1','z$\sim$1.55'})
plt.legend(frameon=False)
plt.legend({'z$\sim$0.35', 'z$\sim$0.1','z$\sim$1.55'})
plt.legend.get_frame().set_linewidth(0.0)
plt.legend({'z$\sim$0.35', 'z$\sim$0.1','z$\sim$1.55'}, 'Box', 'off')
Additionally, when I plotted, I imported two different files and graphed them with a line and with circles respectively. How could I put a line or a circle within the legend key?
The plot:
It's very strange because the command :
plt.legend(frameon=False)
Should work very well.
You can also try this command, to compare :
plt.legend(frameon=None)
You can also read the documentation on this page about plt.legend
I scripted something as example to you :
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0,4,8,13])
y = np.array([0,1,2,3])
fig1, ((ax1, ax2)) = plt.subplots(1, 2)
ax1.plot(x,y, label=u'test')
ax1.legend(loc='upper left', frameon=False)
ax2.plot(x,y, label=u'test2')
ax2.legend(loc='upper left', frameon=None)
plt.show()
Try this if you want to draw only one plot (without subplot)
plt.legend({'z$\sim$0.35', 'z$\sim$0.1','z$\sim$1.55'}, frameon=False)
It is enough one plt.legend. The second one rewrites the first one.
Make sure frameon = False is together with the positional argument in plt.legend(...) if you want to specify the position as well as remove the border. If these arguments are written separately or in sequential, there's an issue of overwriting and the desired effect may not be achieved.
Correct!
plt.legend(loc="lower right", frameon=False)
May not give desired effect when written like this!
plt.legend(loc="lower right") & plt.legend(frameon=False)
Related
I'm trying to change the x axis for my graphs but it's only going through for one of them. My other graph has not changed at all. Here is the code:
fig, (gr0, gr1) = plt.subplots(ncols=2, constrained_layout=True, figsize = (17,7))
#gr0
gr0.plot(data['g1'])
gr0.set_title('text 1')
#gr1
gr1.plot(data['g2'])
gr1.set_title('text 2')
plt.xticks(fontsize=8, rotation=45)
plt.show()
Graphs when the code is ran:
As you can tell by the picture, only the graph on the right has the x-axis updated to where the text is rotated and clearly visible. The other one is still the same :(
The
plt.xticks(..., rotation=45)
call might feel like it applies to the whole figure,
when it's phrased that way.
But behind the scenes it's really making a gca() call
and manipulating that, which of course is gr1 at that point.
You could make a pair of xticks calls,
much as you're already doing for title.
But the fact that you asked about this plot's behavior on SO
indicates that the way it's phrased is not a good match
for clearly communicating the intent.
So let's re-phrase it slightly, avoiding that global.
labels = [
'2022-05-21',
'2022-05-25',
'2022-05-29',
]
gr0.set_xticks(labels=labels, rotation=45)
gr1.set_xticks(labels=labels, rotation=45)
Or consider moving to import seaborn.
In which case the idiom would be the somewhat simpler
gr0.grid.set_xticklabels(rotation=45)
gr1.grid.set_xticklabels(rotation=45)
You can set it per axis using ax.tick_params(labelsize=8, labelrotation=45).
ig, (gr0,gr1) = plt.subplots(ncols=2, constrained_layout=True, figsize = (17,7))
#gr0
gr0.plot(data['g1'])
gr0.set_title('text 1')
gr0.tick_params(labelsize=8, labelrotation=45)
#gr1
gr1.plot(data['g2'])
gr1.set_title('text 2')
gr1.tick_params(labelsize=8, labelrotation=45)
plt.show()
I have this weird thing with the scale of the axis showing out of the figure like:
And what I want to have:
How can I move the scale to the other side of the axis?
x=range(len(ticks))
plt.plot(x,phase1,'r^-',label='$\Delta \phi(U1,I1)$')
plt.plot(x,phase2,'go-',label='$\Delta \phi(U2,I2)$')
plt.plot(x,phase3,'b*-',label='$\Delta \phi(U3,I3)$')
plt.xticks(x,ticks,rotation=45)
plt.xlabel('Messung')
plt.ylabel('$\Delta \phi [^\circ]$')
plt.legend()
plt.show()
The tick_params of your axis can be used to control axes label and ticks location. Set direction to in so that they point into the graph.
And here is a great example if you want different y-axis ranges and colours too.
from matplotlib import pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.tick_params(direction='in', length=6, width=2, colors='r', right=True, labelright='on')
plt.show()
You can use plt.tick_params() to adjust the behaviour of the ticks, documentation can be found here.
For your example you want the ticks to appear inside the figure. Therefore add
plt.tick_params(direction="in")
to your code. Example:
x=range(len(ticks))
plt.plot(x,phase1,'r^-',label='$\Delta \phi(U1,I1)$')
plt.plot(x,phase2,'go-',label='$\Delta \phi(U2,I2)$')
plt.plot(x,phase3,'b*-',label='$\Delta \phi(U3,I3)$')
plt.xticks(x,ticks,rotation=45)
plt.xlabel('Messung')
plt.ylabel('$\Delta \phi [^\circ]$')
plt.legend()
plt.tick_params(direction="in") # Set ticks inside the figure
plt.show()
You can get the ticks to appear on the top and right side of the figure too as shown in your second screenshot by adding:
plt.tick_params(direction="in",top="on",right="on")
If you wanted to make all figures in your Python script have this behaviour then you can add the following at the top of your script (this might be of interest):
import matplotlib
matplotlib.rcParams['xtick.direction'] = "in"
matplotlib.rcParams['ytick.direction'] = "in"
This will save you having to call plt.tick_params() for each figure, which is helpful if you generate lots of figures.
I'm trying to get the legend location in matplotlib. It seems like Legend.get_window_extent() should provide this, but it returns the same value regardless of where the legend is located. Here is an example:
from matplotlib import pyplot as plt
def get_legend_pos(loc):
plt.figure()
plt.plot([0,1],label='Plot')
legend=plt.legend(loc=loc)
plt.draw()
return legend.get_window_extent()
if __name__=='__main__':
# Returns a bbox that goes from (0,0) to (1,1)
print get_legend_pos('upper left')
# Returns the same bbox, even though legend is in a different location!
print get_legend_pos('upper right')
What is the correct way to get the legend location?
You would need to replace plt.draw() by
plt.gcf().canvas.draw()
or, if you have a figure handle, fig.canvas.draw(). This is needed because the legend position is only determined when the canvas is drawn, beforehands it just sits in the same place.
Using plt.draw() is not sufficient, because the drawing the legend requires a valid renderer from the backend in use.
TL DR; Try this:
def get_legend_pos(loc):
plt.figure()
plt.plot([0,1],label='Plot')
legend=plt.legend(loc=loc)
plt.draw()
plt.pause(0.0001)
return legend.get_window_extent()
Here is why
So I tried your code in Jupyter and I can reproduce the behavior with option
%matplotlib notebook
However for
%matplotlib inline
I am getting correct response
Bbox(x0=60.0, y0=230.6, x1=125.69999999999999, y1=253.2)
Bbox(x0=317.1, y0=230.6, x1=382.8, y1=253.2)
It looks like in the first case the legend position is not evaluated until the execution finishes. Here is an example that proves it, in the first cell I execute
fig = plt.figure()
plt.plot([0,1],label='Plot')
legend=plt.legend(loc='upper left')
plt.draw()
print(legend.get_window_extent())
Outputs Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0).
In the next cell re-evaluate the last expression
print(legend.get_window_extent())
Outputs Bbox(x0=88.0, y0=396.2, x1=175.725, y1=424.0)
You probably just need to add plt.pause() to enforce the evaluation.
I've got a pandas dataframe with 4 columns and a date range as the index. After showing the trend lines on four subplots using this code, I realized I don't want the y axis ticks or labels, but I can't find any advice on removing them from the subplots; everything I try only works on the bottom plot.
plot4 = CZBCdf2.plot(subplots=True,figsize=(10,4),sharex=True)
The typical way of removing axis in matplotlib is:
import matplotlib.pyplot as plt
plt.axis('off')
This, however, is a general instruction in matplotlib. To set the axis to invisible you can do (using a subplot):
ax.xaxis.set_visible(False) # same for y axis.
You seem to be calling the plot from other source. If this instructions don't do the stuff you need provide more of your code to see what might be the procedure to achieve that.
A complete solution to remove anything around the plot
figure, axis = plt.subplots(1, figsize=[10,3])
axis.plot(...)
axis.xaxis.set_visible(False)
axis.yaxis.set_visible(False)
for spine in ['top', 'right', 'left', 'bottom']:
axis.spines[spine].set_visible(False)
figure.savefig('demo.png', bbox_inches='tight', transparent="True", pad_inches=0, )
Set yticks=[]
So, in your example:
plot4 = CZBCdf2.plot(subplots=True,figsize=(10,4),sharex=True, yticks=[])
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