I am plotting 2 lines and a dot, X axis is a date range. The dot is most important, but it appears on the boundary of the plot. I want to "expand" the plot further right so that the dot position is more visible.
In other words I want to expand the X axis without adding new values to Y values of lines. However if I just add a few dates to X values of lines I get the "x and y dimensions must be equal" error. I tried to add a few np.NaN values to Y so that dimensions are equal, but then I get an error "integer required".
My plot:
My code:
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
plot_x = train_original.index.values
train_y = train_original.values
ax1.plot(plot_x, train_y, 'grey')
x = np.concatenate([np.array([train_original.index.values[-1]]), test_original.index.values])
y = np.concatenate([np.array([train_original.dropna().values[-1]]), test_original.dropna().values])
ax1.plot(x, y, color='grey')
ax1.plot(list(predicted.index.values), list(predicted.values), 'ro')
ax1.axvline(x=train_end, alpha=0.7, linestyle='--',color='blue')
plt.show()
There are a couple of ways to do this.
An easy, automatic way to do this, without needing knowledge of the existing xlim is to use ax.margins. This will add a certain fraction of the data limits to either side of the plot. For example:
ax.margins(x=0.1)
will add 10% of the current x range to both ends of the plot.
Another method is to explicitly set the x limits using ax.set_xlim.
Just change the xlim(). Something like:
xmin, xmax = plt.xlim() # return the current xlim
plt.xlim(xmax=xmax+1)
Related
This might be a very simple question, but I just could not get the trick for this problem .
I want to plot multiple subplots, but when I have done that and use my defined axis limits, I find there is overlapping of axis. Y axis should be same in each column. Any tips to remove this:
My simplified script is here:
column = 2
num=len(sta_files)
fig, axes = plt.subplots(nrows=num, ncols=column,figsize=(15,15))
n=0
for event_file in sta_files:
axes[n,0].plot(np.arange(0,len(st[0].data))*1/sampling_rate,
st[0].data+i,color='k',linewidth=0.7)
axes[n,0].set_xlim((0, 35))
spl2 = st[0]
fig = spl2.spectrogram(show=False, axes=axes[n,1])
mappable = axes[n,1].images[0]
Here is my output:
I have created a figure that has two y axes that are sharing one x axis. The y axes are correlated to each other: the values of the left y-axis are an input to an equation that gives the values of the right y-axis. To correlate the two, I set the y ticks on each axis to be the same. Then I tried to use a function (myticks) to label the y ticks on each axis with the proper labels using set_major_formatter(ticker.FuncFormatter(myticks)). The y ticks are in the correct position on each axes and the labels are correct on the left axis, but the labels are incorrect on the right axis. For some reason, the left axis labels are showing up on the right axis as well. The values of the right axis should be the values present in right_y2. I'm brand new to Python, so any help is greatly appreciated!
#plot
fig = plt.figure(figsize=(3,4))
ax1 = fig.add_subplot(111)
y =[1.9E19,1E20,5E20,1.8E21,1E22,1.9E22,1.15E23]
ax1.plot(2,y[0],marker='o')
ax1.plot(2,y[1],marker='o')
ax1.plot(2,y[2],marker='o')
ax1.plot(2,y[3],marker='o')
ax1.plot(2,y[4],marker='o')
ax1.plot(2,y[5],marker='o')
ax1.plot(2,y[6],marker='o')
ax1.set_yscale("log")
ax1.set_ylim(1E19,2E23)
ax1.set_yticks(y)
def myticks(left_y,y):
exponent = int(np.log10(left_y))
coeff = left_y/10**exponent
return r"${:2.0f} \times 10^{{ {:2d} }}$".format(coeff,exponent)
ax1.yaxis.set_major_formatter(ticker.FuncFormatter(myticks))
ax2 = ax1.twinx()
ax2.set_yscale("log")
ax2.set_ylim(1E19,2E23)
ax2.set_yticks(y)
def myticks2(right_y2,y):
exponent2 = int(np.log10(right_y2))
coeff2 = right_y2/10**exponent2
return r"${:2.0f} \times 10^{{ {:2d} }}$".format(coeff2,exponent2)
ax2.yaxis.set_major_formatter(ticker.FuncFormatter(myticks2)
where
left_y =[1.9E19,1E20,5E20,1.8E21,1E22,1.9E22,1.15E23]
right_y2 =[5.3E12,3.8E13,1.3E14,2.7E14,5E14,9.6E14,3E15]
I get the following figure:
enter image description here
I need to create a graph with uneven 'x axis' and label them.
For example:
x = [2,5,10,20,30]
y = [100,200,312,788,123]
I want the x axis on plot to be spaced as x itself. I solved the issue with following code. But instead of exact x values I would like to name them in the order of occurrence, ie 1,2,3,4,5 in place of 2,5,10,20,30.
Thank you
plt.figure(30)
plt.plot(x,y,color='b',alpha=1)
plt.title('R_variation',fontsize=20)
plt.ylabel(r'R',fontsize=20,color='k')
plt.xlabel('Time (hr)',fontsize=20,color='k')
plt.xticks(x, rotation='vertical')
plt.grid()
plt.show()
I want to make x and y axes be of equal lengths (i.e the plot minus the legend should be square ). I wish to plot the legend outside (I have already been able to put legend outside the box). The span of x axis in the data (x_max - x_min) is not the same as the span of y axis in the data (y_max - y_min).
This is the relevant part of the code that I have at the moment:
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize=15 )
plt.axis('equal')
plt.tight_layout()
The following link is an example of an output plot that I am getting : plot
How can I do this?
Would plt.axis('scaled') be what you're after? That would produce a square plot, if the data limits are of equal difference.
If they are not, you could get a square plot by setting the aspect of the axes to the ratio of xlimits and ylimits.
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1,2)
ax1.plot([-2.5, 2.5], [-4,13], "s-")
ax1.axis("scaled")
ax2.plot([-2.5, 2.5], [-4,13], "s-")
ax2.set_aspect(np.diff(ax2.get_xlim())/np.diff(ax2.get_ylim()))
plt.show()
One option you have to is manually set the limits, assuming that you know the size of your dataset.
axes = plt.gca()
axes.set_xlim([xmin,xmax])
axes.set_ylim([ymin,ymax])
A better option would be to iterate through your data to find the maximum x- and y-coordinates, take the greater of those two numbers, add a little bit more to that value to act as a buffer, and set xmax and ymax to that new value. You can use a similar method to set xmin and ymin: instead of finding the maximums, find the minimums.
To put the legend outside of the plot, I would look at this question: How to put the legend out of the plot
I have some code below which plots 3 sets of random numbers by adding them to a plot (simulating real world data gathered from say a temperature sensor).
I am attempting to make 2 scales on the same plot.
Here, y2List is negative and this is the data set that I would like to create the second axis for. I figured out how to do this using other questions on here.
The problem is that when each data point is added, the second y axis ticks are shown again so that the second y axis is very crowded with numbers. I can get round this by setting a limit on the second y axis, which produces an image like this:
The second y axis is slightly darker than the others, and this is because python is plotting the same numbers on top of the existing ones after each point is plotted (I can tell because the numbers get darker as each point is plotted)
My question... is there a way to make the second y axis only plot the second scale only once? This is obviously just to make the plot aesthetically pleasing but every little helps!
My code is below:
plt.ion() # enable interactivity
def makeFig():
ax.plot(xList, yList, color='blue', label='something1' if x == 0 else '')
ax.plot(xList, y1List, color='red', label='something2' if x == 0 else '')
ax2 = ax.twinx()
ax2.plot(xList, y2List, color='orange', label='something else' if x == 0 else '')
ax2.set_ylim(-20,0)
xList=list()
yList=list()
y1List=list()
y2List=list()
x=0
while x<11:
fig1=plt.figure(1)
ax = fig1.add_subplot(111)
x_1 = datetime.datetime.now()
date_formatter = DateFormatter('%H:%M:%S')
y=np.random.random()
y1=np.random.random() *3
y2=np.random.random() *(-13)
xList.append(x_1)
yList.append(y)
y1List.append(y1)
y2List.append(y2)
makeFig()
plt.gcf().autofmt_xdate()
ax = plt.gca()
ax.xaxis.set_major_formatter(date_formatter)
max_xticks = 10
xloc = plt.MaxNLocator(max_xticks)
ax.xaxis.set_major_locator(xloc)
plt.get_current_fig_manager().window.wm_geometry("940x700+5+0")
plt.draw()
plt.legend(loc=2, bbox_to_anchor=(1, 0.5), prop={'size':10})
x+=1
plt.pause(0.5)
You should move the creation of the figure and the twin axes outside of your loop. They only need to be done once.
Specifically, move fig1=plt.figure(1), ax = fig1.add_subplot(111) and ax2 = ax.twinx() outside the loop.