from matplotlib import pyplot as plt
fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True)
fig.show()
Returns this figure:
But I want the x-axis labels below the first plot, not the second, like shown below. How can I achieve this?
There is an example in the official reference, so I answered it by referring to it: In the tick parameter, set the bottom label to false.
import matplotlib.pyplot as plt
ax0 = plt.subplot(211)
ax1 = plt.subplot(212, sharex=ax0, sharey=ax0)
#plt.plot([],[])
plt.tick_params('x', labelbottom=False)
#print(ax1.get_xticks())
plt.show()
The answer from #r-beginners brought me to a solution that also works when using the plt.subplots shortcut instead of instantiating each axis separately.
from matplotlib import pyplot as plt
fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True)
plt.tick_params('x', labelbottom=False, labeltop=True)
fig.show()
he essential part is plt.tick_params which take keyword arguments labeltop or labelbottom (as well as labelleft or labelright for shared axis on several columns) to select / deselect each axis individually.
Related
I'm messing around with some plot styles and ran into a curiosity. I have a plot with twinx() to produce ticks on the right-hand side as well as the left. I want to stagger some ticks, some going farther out that others.
I can add padding to any tick on any axes and push out the text via ax.yaxis.get_major_ticks()[1].set_pad(), but when I try to lengthen the tick via ax.yaxis.get_major_ticks()[1].tick1line.set_markersize(), it works for all axes EXCEPT the right side. Any insight?
Please see the code below. I've tried switching up the axis (ax1, ax2) and index.
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
t = np.linspace(0,5)
x = np.exp(-t)*np.sin(2*t)
fig, ax1 = plt.subplots()
ax1.plot(t, x, alpha=0.0)
ax2 = ax1.twinx()
ax2.plot(t, x, alpha=1.0)
ax1.set_xticks([0,1,2])
ax1.set_yticks([0.1, 0.2])
ax2.set_yticks([0.3, 0.4, 0.5])
ax2.set_xticks([1,2,3])
ax1.grid(True, color='lightgray')
ax2.grid(True, color='lightgray')
for a in [ax1, ax2]:
a.spines["top"].set_visible(False)
a.spines["right"].set_visible(False)
a.spines["left"].set_visible(False)
a.spines["bottom"].set_visible(False)
ax1.set_axisbelow(True)
ax2.set_axisbelow(True)
ax1.xaxis.get_major_ticks()[1].set_pad(15) #
ax1.xaxis.get_major_ticks()[1].tick1line.set_markersize(15)
ax1.yaxis.get_major_ticks()[1].set_pad(15) #
ax1.yaxis.get_major_ticks()[1].tick1line.set_markersize(15)
ax2.yaxis.get_major_ticks()[1].set_pad(15) #
ax2.yaxis.get_major_ticks()[1].tick1line.set_markersize(15)
plt.savefig('fig.pdf')
plt.show()
You need to use tick2line instead of tick1line, since that's the one referring to the top/right axis, according to the documentation.
Change ax2.yaxis.get_major_ticks()[1].tick1line.set_markersize(15) for:
ax2.yaxis.get_major_ticks()[1].tick2line.set_markersize(15)
Result:
I have an odd number of subplots like so:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2, sharex=True)
for i, ax in enumerate(axes.flat):
ax.plot(range(10))
fig.delaxes(axes.flat[-1])
I want them all to have the same x-axis, but easily add the x-ticks back to the plot on the right, since there is no longer a 4th plot.
It seems like there should be an easier/cleaner solution than adding each subplot manually (similar to this answer), but I can't seem to find anything. Thanks.
you can use setp to make the xtick labels visible for ax[0][1] like this
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2, sharex=True)
for i, ax in enumerate(axes.flat):
ax.plot(range(10))
# for matploltib version 2.0.1
plt.setp(axes[0][1].get_xticklabels(), visible=True)
# for matplotlib version 2.1.1
axes[0][1].xaxis.set_tick_params(which='both', labelbottom=True, labeltop=False)
fig.delaxes(axes.flat[-1])
plt.show()
which will result in
I have two different sets of data with a common index, and I want to represent the first one as a barplot and the second one as a lineplot in the same graph. My current approach is similar to the following.
ax = pt.a.plot(alpha = .75, kind = 'bar')
ax2 = ax.twinx()
ax2.plot(ax.get_xticks(), pt.b.values, alpha = .75, color = 'r')
And the result is similar to this
This image is really nice and almost right. My only problem is that ax.twinx() seems to create a new canvas on top of the previous one, and the white lines are clearly seen on top of the barplot.
Is there any way to plot this without including the white lines?
You can use twinx() method along with seaborn to create a seperate y-axis, one for the lineplot and the other for the barplot. To control the style of the plot (default style of seaborn is darkgrid), you can use set_style method and specify the preferred theme. If you set style=None it resets to white background without the gridlines. You can also try whitegrid. If you want to further customize the gridlines, you can do it on the axis level using the ax2.grid(False).
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
matplotlib.rc_file_defaults()
ax1 = sns.set_style(style=None, rc=None )
fig, ax1 = plt.subplots(figsize=(12,6))
sns.lineplot(data = df['y_var_1'], marker='o', sort = False, ax=ax1)
ax2 = ax1.twinx()
sns.barplot(data = df, x='x_var', y='y_var_2', alpha=0.5, ax=ax2)
You have to remove grid lines of the second axis. Add to the code ax2.grid(False). However y-ticks of the second axis will be not align to y-ticks of the first y-axis, like here:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(pd.Series(np.random.uniform(0,1,size=10)), color='g')
ax2 = ax1.twinx()
ax2.plot(pd.Series(np.random.uniform(0,17,size=10)), color='r')
ax2.grid(False)
plt.show()
In matplotlib what is the way to have tick labels both at the bottom and in the top x axis? I have searched a lot and still can't find how to do it.
Sorry, I lied in the comments. You can do this easily (but it seems to be badly documented)
fig, ax = plt.subplots(1, 1)
ax.xaxis.set_tick_params(labeltop='on')
You can do it with twiny():
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
X2tick_location= ax1.xaxis.get_ticklocs() #Get the tick locations in data coordinates as a numpy array
ax2.set_xticks(X2tick_location)
ax2.set_xticklabels(X2tick_location)
plt.show()
Have a look to this question too for more elaborate plots.
This seems to be the standard way as of v3.5:
fig, ax = plt.subplots()
ax.tick_params('x', top=True, labeltop=True)
Note that the top keyword draws the ticks and the labeltop keyword draws the labels. Documentation here.
I'm using python + matplotlib and I'm having two plots share an axis. If you try to set graph1.set_xticklabels([]) while sharing an axis, it has no effect because it is shared. Is there a way to share the axis AND be able to hide the x axis of one plot?
This is a common gotcha when using shared axes.
Fortunately, there's a simple fix: use plt.setp(ax.get_xticklabels(), visible=False) to make the labels invisible on just one axis.
This is equivalent to [label.set_visible(False) for label in ax.get_xticklabels()], for whatever it's worth. setp will automatically operate on an iterable of matplotlib objects, as well as individual objects.
As an example:
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1)
ax1.plot(range(10), 'b-')
ax2 = fig.add_subplot(2,1,2, sharex=ax1)
ax2.plot(range(10), 'r-')
plt.setp(ax1.get_xticklabels(), visible=False)
plt.show()
Per a thread on matplotlib-users, you could use
import matplotlib.pyplot as plt
for ax in plt.gcf().axes:
try:
ax.label_outer()
except:
pass
You could use Axes.tick_params():
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212, sharex=ax1)
ax1.tick_params(labelbottom=False)
You can share the axes during subplot creation with plt.subplots as
fig, axes = plt.subplots(nrows=2, sharex=True)
This will automatically turn the ticklabels for inner axes off.
Complete example:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2, sharex=True)
axes[0].plot([1,2,3])
axes[1].plot([3,2,1])
plt.show()
Unfortunately, I am not allowed to comment on esmit's answer (which is the best solution in my opinion, thanks esmit), so I have to write my comment as a new answer: I put his solution into a simple function
def remove_inner_ticklabels(fig):
for ax in fig.axes:
try:
ax.label_outer()
except:
pass
which you can call before plt.show(). Joe Kington's answer did not work for me for some reason.