I make a loop over two cases and for each case I try to make a plot.
for col_name in ['col2','col3']:
x_min = min(df['col1'].min(), df[col_name].min())
x_max = max(df['col1'].max(), df[col_name].max())
plt.xlim([x_min,x_max])
plt.ylim([x_min,x_max])
plt.axes().set_aspect('equal')
plt.scatter(df['col1'], df[col_name])
As a result I get one plot in my IPython notebook. Does anyone know how to overcome this problem?
You need to call figure() more than once.
for col_name in ['col2','col3']:
plt = figure() #This gives you a new figure to plot in
x_min = min(df['col1'].min(), df[col_name].min())
x_max = max(df['col1'].max(), df[col_name].max())
plt.xlim([x_min,x_max])
plt.ylim([x_min,x_max])
plt.axes().set_aspect('equal')
plt.scatter(df['col1'], df[col_name])
I would just use two figures if I want them on different windows.
Something like this ought to work.
>>> for i in range(3):
xAxis = [randint(1, 5) for _ in range(10)]
plt.figure(1)
plt.plot(xAxis)
plt.show()
xAxis2 = [randint(1, 5) for _ in range(10)]
plt.figure(2)
plt.plot(xAxis2)
plt.show()
It gave me six consecutive figures.
Since, you need a new figure for every iteration, do.
for index, col_name in ['col2','col3']:
plt.figure(index)
# Do the plotting.
Related
I'm working on Jupyter notebook, with recession data. I want to make a FloatSlider that takes values from a column(it contains 737 observations for Yield spreads between 1962-2020). Then I want to use that to interact it with another column and plot it. I want see how changing Yield spread on the slider will change the graph of the other variable.
I don't have any concrete code for this because I am still figuring if this is possible. Would appreciate any help!
So far I only have this:
def plot_func(m):
#m = m_clean['Yield_Spread'].tolist()
fig = plt.figure()
ax = fig.subplots()
ax.set_title('y_pred_Probit')
fig1 = ax.plot(m_clean['Yield_Spread'], color='blue', label = '' , linewidth = 2)
#ax2 = ax.twinx()
fig2= ax.plot(m_clean['y_pred_Probit'],color='brown', label = 'y_pred_Probit', linewidth = 2)
plt.show()
smoo = interact(plot_func, m = FloatSlider(min=0.0,max=1.0,step=0.5, continuous_update=True))
but I need to assign m as the values of Yield_Spread and I also want it to be updated using an update function.
I am trying to plot real time data. I managed to plot the data but I would like for the bar graph to go up and down on a single x-value rather than produce new x-values for every new datapoint. I believe I have to replace the function x.append(i) with something like a replace, any ideas? Thank you!!
So far this is what I came up with:
import time
import psutil
import matplotlib.pyplot as plt
%matplotlib notebook
fig = plt.figure()
ax = fig.add_subplot(111)
fig.show()
plt.axis('off')
i = 0
x, y = [], []
while True:
x.append(i)
y.append(psutil.cpu_percent())
ax.bar(x, y, color='b')
fig.canvas.draw()
ax.set_xlim(left=max(0, i-50), right=i+50)
time.sleep(0.1)
i += 1
For the bar graph you can create a list inside the while loop, and instantly update it there. First you need to import a random in order get random value for y axis, or you can use cpu_percent.
import psutil
import random
These two should work.
And then:
while True:
x_axis = [str(_) for _ in range(100, 200)]
y_axis = [8 * random.random() for _ in range(100, 200)]
ax.bar(x, y, color='b')
fig.canvas.draw()
time.sleep(0.1)
However, matplotlib is not convenient for real data plotting, I strongly recommend you to use bokeh. You can find bokeh documentation here. It is really cool for creating any kind of real time plot. And at the same time, you can integrate it with your web browser. Hope this will help you)
If you just want to display the latest value, you can consider doing something like:
plt.ion()
graph = plt.bar(["Now"], [0])[0]
plt.axis('off')
i = 0
data = {}
while True:
cpu_percent = psutil.cpu_percent()
graph.set_ydata(cpu_percent)
plt.draw()
plt.pause(0.1)
data[i] = cpu_percent
i += 1
This way, you still have a record of all the datapoints to play with later (x, y) but you will only display 1 x value at a time on the graph.
Further reading
say I was testing a range of parameters of a clustering algorithm and I wanted to write python code that would plot all the results of the algorithm in subplots 2 to a row
is there a way to do this without pre-calculating how many total plots you would need?
something like:
for c in range(3,10):
k = KMeans(n_clusters=c)
plt.subplots(_, 2, _)
plt.scatter(data=data, x='x', y='y', c=k.fit_predict(data))
... and then it would just plot 'data' with 'c' clusters 2 plots per row until it ran out of stuff to plot.
thanks!
This answer from the question Dynamically add/create subplots in matplotlib explains a way to do it:
https://stackoverflow.com/a/29962074/3827277
verbatim copy & paste:
import matplotlib.pyplot as plt
# Start with one
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3])
# Now later you get a new subplot; change the geometry of the existing
n = len(fig.axes)
for i in range(n):
fig.axes[i].change_geometry(n+1, 1, i+1)
# Add the new
ax = fig.add_subplot(n+1, 1, n+1)
ax.plot([4,5,6])
plt.show()
Here is the code of plotting the figures. But why are there always two empty figures before the third expected figure, it seems I created two blank fig.
And I cannot save the figure in my local computer fig.savefig('Sens.png'). There is an error The C++ part of the object has been deleted, attribute access no longer allowed(actually successfully saved only for one time).
fig = plt.figure(figsize=(10,10))
m = 1
for s in dataList:
plt.subplot(2,2,m)
f = interp1d(FXSpotList, s, 'cubic')
xnew = np.linspace(FXSpotList[0], FXSpotList[-1], 40, True)
plt.plot(xnew, f(xnew), '-')
plt.xlabel('Spot')
plt.ylabel(titleList[m-1])
plt.axvline(x=tradeTest.Pair().Spot(), linestyle='--')
plt.axhline(y=0, linestyle='--')
m = m + 1
plt.figtext(0.5, 0.01, 'Type='+str(tradeTest.Types()[0]), ha='center')
plt.tight_layout()
plt.show()
plt.close()
fig.savefig('Sens.png')
Although you did not provide a Minimal, Complete, and Verifiable example, it is obvious that there are things wrong with your loop construction. You show, close, then save the plot in every loop, which is probably not, what you are intending to do. A minimal example of your loop would be
import numpy as np
from matplotlib import pyplot as plt
#sample list to iterate over
dataList = ["fig1", "fig2", "fig3"]
plt.figure(figsize=(10,10))
#loop over the list, retrieve data entries and index
for i, s in enumerate(dataList):
#define position of the plot in a 2 x 2 grid
plt.subplot(2, 2, i + 1)
#random plot, insert your calculations here
plt.plot(range(3), np.random.randint(0, 10, 3))
#utilize list data
plt.title(s)
#save figure
plt.savefig('test.png')
#show figure
plt.show()
I have two lists, x_axis which is list of time in the format of '12:30:00'. The y-axis is percent values. I need to plot all the values on a graph, however since x-axis string is too long they overlap. Is there anyway I can have matplotlib not show every single time on x-axis? Any help would be appreciated.
You could rotate and print every 2nd ticklabel:
_ = plt.plot(df['str_time'], df.Pct, 'ro')
ax = plt.gca()
plt.axis([0,24,0,50])
plt.xticks(rotation=90)
for label in ax.get_xaxis().get_ticklabels()[::2]:
label.set_visible(False)
Output:
You can rotate your label to show the list time using the below code.
plt.xticks(rotation=90)
One way to do this automatically is by using autofmt_xdate
fig.autofmt_xdate():
for getting fig object you will have to call the subplot functions
fig, ax = plt.subplots()
Works really well
I needed to step x axis digits instead of rotating.
ax.set_xticks(np.arange(0, max_number, 5)) #step 5 digits
Output: