I am trying to plot two dataframes on the same plot using ax.twinx().
the first plots fine:
figi, ax1=plt.subplots()
ax1.plot(locals()[edfn].datetime, locals()[edfn].ic_mean, label='ic mean')
ax2=ax1.twinx()
ax1.legend(title='gauge name', loc='upper left')
ax1.set_ylabel('Rain (mm)', rotation=90)
ax1.set_xlabel('Datetime')
ax1.tick_params(axis='x',rotation=90)
#for xx in gl2:
ax2.plot(locals()[dfn]['datetime'], locals()[dfn][xx]*100, label=xx)
# mfmt=mds.DateFormatter('%m-%d-%H')
# ax1.xaxis.set_major_formatter(mfmt)
# ax1.xaxis.set_(interval=1)
#ax2.tick_params(axis='x', which='both', bottom=False)
#ax2.tick_params(labelbottom=False)
#plt.setp(ax2.get_xticklabels(),visible=False)
figi.tight_layout()
but when I add the second, which has a nuch finer scale temporal resolution (10 mins as opposed to one hour), it adds every timepoint as a tick on the x axis.
figi, ax1=plt.subplots()
ax1.plot(locals()[edfn].datetime, locals()[edfn].ic_mean, label='ic mean')
ax2=ax1.twinx()
ax1.legend(title='gauge name', loc='upper left')
ax1.set_ylabel('Rain (mm)', rotation=90)
ax1.set_xlabel('Datetime')
ax1.tick_params(axis='x',rotation=90)
#for xx in gl2:
ax2.plot(locals()[dfn]['datetime'], locals()[dfn][xx]*100, label=xx)
# mfmt=mds.DateFormatter('%m-%d-%H')
# ax1.xaxis.set_major_formatter(mfmt)
# ax1.xaxis.set_(interval=1)
#ax2.tick_params(axis='x', which='both', bottom=False)
#ax2.tick_params(labelbottom=False)
#plt.setp(ax2.get_xticklabels(),visible=False)
igi.tight_layout()
As you can see i have tried many different commands , mainly from answers on here, but it just doesn't seem to work!
Related
I have an ax.stackplot showing population of different groups over time. The x-axis is time and the y-axis is population. I am showing time at major labels 1 year and minor labels 1 month, however, changes in the data occur more frequently at "events". I'd like to show labels for these events along the x-axis, kind of how I have it sketched out in the image here:
I've attempted adding a second axis with plt.axes(), but this second axis is overwriting the ticks of my first axis for some reason. Does anyone have any suggestions for how to accomplish this?
Thank you!
If you don't have too many points, I think the best way to do this is adding text to your axes using ax.text:
from matplotlib import pyplot
import matplotlib
import numpy as np
# Random plot
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
fig, ax = pyplot.subplots()
ax.plot(t, s)
# ax.text(x, y, text, rotation)
ax.text(0, -0.35, "Event 1", rotation=90) # rotation=90 is easier to read, for me
ax.text(0.5, -0.35, "Event 2", rotation=-90) # opposite rotation
ax.text(0.75, -0.35, "Event 3", rotation=-90)
# This gives some space at the bottom of the figure
# so that the text is visible
fig.subplots_adjust(bottom=0.2)
pyplot.show()
Result:
Check the Axes.text documentation for more info.
Thank you for the responses, I was able to come up with a solution based on your suggestions. The solution involves using ax.twiny() to create a second axes object, and then specifying the second x-axis data points and labels. Below is a simple example for those interested:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
# Create some meaningless data for testing.
x = np.arange(0, 10)
y = np.full(10, len(x))
# Set up figure and set axes parameters.
fig = plt.figure(num=None, figsize=(10, 8), dpi=80, facecolor='w', edgecolor='k')
ax = plt.axes()
ax.xaxis.set_minor_locator(ticker.FixedLocator([1, 3, 5, 7, 9]))
# Get a second axes (for secondary labels) and set parameters.
axl = ax.twiny()
axl.tick_params(axis='x', bottom=True, labelbottom=True, labeltop=False, top=False, length=15, colors=[.5,.5,.5])
# Plot data on primary axes
ax.bar(x, y)
interval = ax.xaxis.get_view_interval()
# Set label properties on secondary axes (for secondary labels)
axl.xaxis.set_view_interval(*interval)
axl.xaxis.set_ticklabels(['a', 'b'])
axl_loc = ticker.FixedLocator([0.5, 4.75])
axl.xaxis.set_major_locator(axl_loc)
plt.show()
How can I pass an argument to show all of the x value so one could read it? As well, how can I show many lines of data, and with alegend?
plt. plot(a, b, linewidth=2.0 )
You could display only n-th x-ticks and make a plot bigger to accomodate more labels.
df = pd.DataFrame(data=np.random.rand(10), index=pd.Series(np.random.rand(10)).astype(str)+'_index')
0
0.007017115173211574_index 0.963285
0.434969747965131_index 0.547248
0.18021258326382017_index 0.719402
0.7815848046772174_index 0.061448
0.8856299613744312_index 0.771062
0.16840431221766328_index 0.524256
0.8662531211345982_index 0.528706
0.6389453277004077_index 0.287410
0.7444490769967744_index 0.513631
0.8965709043061524_index 0.892011
plt.subplots(figsize=(20,15)) # make plot bigger
plt.plot(df.index, df[0]*2, linewidth=.9) # plot several lines
plt.plot(df.index, df[0].rename('1'),linewidth=.9) # plot several lines
plt.xticks(df.index[::2]) # tick every 2nd label on x axis.
plt.legend() # show legend
I have 2 functions , one plots a time series line, other plots the autocrrelation.
def plotacorr(dfasst):
# Plot autocorrelation
plt.acorr(dfasst, maxlags=3)
# Add labels to autocorrelation plot
plt.title('Autocorrelation of Asset Balances with previous Months Balances')
plt.xlabel('Lag in Months')
plt.ylabel('Autocorrelation')
# Display the autocorrelation plot
#plt.show()
plt.savefig('C:/acorr_assets.jpeg')
def plottrend(df_acctsmry2):
fig, ax = plt.subplots()
fmt = '${x:,.0f}'
tick = mtick.StrMethodFormatter(fmt)
ax.yaxis.set_major_formatter(tick)
df_acctsmry2.plot(x='REPORTING_DATE',ax=ax,figsize=(20,12))
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.xlabel('REPORTING_DATE', fontsize=18)
#plt.show()
plt.savefig('C:/output.jpeg')
I first call plottrend, followed by plotacorr
But it seems that somehow the plt object is getting sharedbetween the 2 plots, so in the autocorrelation plot, I see the same result as plottrend.
Uncomment the plt.show() on each function, that should do it (or call a plt.show() between the call to functions).
I have produced the graph shown below as intended with matplotlib and Pandas except two problems:
I can't get rid of the x axes labels (Year) for the three plots at the top (things I have tried are commented out in the code attached), and I could not centre the y axis label.
It seem trivial but I can't get it to work.
Any suggestions?
Thanks
fig, axes = plt.subplots(nrows=4, ncols=1, sharex=True, figsize=(12, 12))
for i, crop in enumerate(['Cabbage','Green beans','Potato', 'Wheat']):
mean_irr_soil[crop].plot(kind='bar', ax=axes[i], title=crop, grid=False)
axes[i].set_ylim([0, 700]) # set limit for all y axes
axes[i].tick_params(axis='x', top='off') # remove top ticks
axes[i].tick_params(axis='y', right='off') # remove right-hand ticks
axes[i].tick_params(axis='x', labelbottom='off')
if i is not 0:
axes[i].legend_.remove() # all but top graph
# if i is not 3:
# axes[i].get_xaxis().set_visible(False) # remove axis all together
# axes[i].tick_params(axis='x', labelbottom='off')
# axes[i].set_xticklabels([]) # remove x-axis labels
axes[0].legend(bbox_to_anchor=(1.1, 1.4))
axes[2].set_ylabel('Mean irrigation requirements in mm')
You need the xlabel attribute: ax.set_xlabel("").
Is there a way to get rid of tick labels altogether when creating an array of subplots in Matplotlib? I am currently needing to specify each plot based on the row and column of a larger data set to which the plot corresponds. I've attempted to use the ax.set_xticks([]) and the similar y-axis command, to no avail.
I recognize that it's probably an unusual request to want to make a plot with no axis data whatsoever, but that's what I need. And I need it to automatically apply to all of the subplots in the array.
You have the right method. Maybe you are not applying the set_xticks to the correct axes.
An example:
import matplotlib.pyplot as plt
import numpy as np
ncols = 5
nrows = 3
# create the plots
fig = plt.figure()
axes = [ fig.add_subplot(nrows, ncols, r * ncols + c) for r in range(0, nrows) for c in range(0, ncols) ]
# add some data
for ax in axes:
ax.plot(np.random.random(10), np.random.random(10), '.')
# remove the x and y ticks
for ax in axes:
ax.set_xticks([])
ax.set_yticks([])
This gives:
Note that each axis instance is stored in a list (axes) and then they can be easily manipulated. As usual, there are several ways of doing this, this is just an example.
Even more concise than #DrV 's answer, remixing #mwaskom's comment, a complete and total one-liner to get rid of all axes in all subplots:
# do some plotting...
plt.subplot(121),plt.imshow(image1)
plt.subplot(122),plt.imshow(image2)
# ....
# one liner to remove *all axes in all subplots*
plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[]);
Note: this must be called before any calls to plt.show()
The commands are the same for subplots
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
ax1.plot([1,2])
ax1.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom='off', # ticks along the bottom edge are off
top='off', # ticks along the top edge are off
labelbottom='off' # labels along the bottom edge are off)
)
plt.draw()
You can get rid of the default subplot x and y ticks with simply running the following codes:
fig, ax = plt.subplots()
ax.xaxis.set_major_locator(plt.NullLocator())
ax.yaxis.set_major_locator(plt.NullLocator())
for i in range(3):
ax = fig.add_subplot(3, 1, i+1)
...
Just by adding the 2 aforementioned lines just after fig, ax = plt.subplots() you can remove the default ticks.
One can remove the xticks or yticks by
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
If you want to turn off also the spines, so having no axis at all, you can use:
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
And if you want to turn everything off at once, use:
ax.axis("off")