I created several plots using the following code:
a = np.arange(1,6)
b = np.arange(2, 11, 2)
c = np.arange(100, 1000, 200)
d = np.arange(0.2, 1.1, 0.2)
figs = []
for i in np.arange(1, 6):
fig, ax = plt.subplots()
ax.bar(a, b/i, width = d/10)
ax.scatter(a, b/i, s=c*i)
figs.append(fig)
fig = plt.figure()
ani = matplotlib.animation.ArtistAnimation(fig, figs)
plt.show()
And the graphs look like
I put the figure objects into a list and used the ArtistAnimation feature, but nothing seems to show. I'm also adding interactive features to each graph such as hover boxes so I can't just save the plots and make gifs. Can someone point out where I need to change my code? Also, is there any way to turn off the display of graphs when I generate them so that there won't be too many different graphs displaying at the same time?
Related
My problem lies within the colorbar after generating subplots based on a data within certain gridpoints.
If I generate a single Snapshot, the colorbar will appear:
fig1, ax = plt.subplots()
im = ax.imshow(data[0])
fig1.colorbar(im, ax=ax,label='blublub')
ax.set_title = ('blabla')
But when I generate a loop for several subplots like, I cannot implement showing the colorbar at least once at the bottom of the figure.
fig = plt.figure(figsize = (15, 15))
for t in range(17):
plt.subplot(5, 5, t + 1)
plt.pcolor(x1grid, x2grid, data[t])
txt = "t = {t:.1f}"
plt.title(txt.format(t = time[t]))
I reviewed all questions on this platform, but could not implement a single one within my code. If my question is covered by already existing one, pls excuse me. I will review it and delete my post.
Thanks in advance
Maria
If you want to add a colorbar to each subplot in your loop, you can use the plt.colorbar() function in the same way as you did for the single subplot. However, instead of passing the im object as the first argument, you should pass the mappable object returned by plt.pcolor(). For example:
fig = plt.figure(figsize = (15, 15))
for t in range(17):
plt.subplot(5, 5, t + 1)
pc = plt.pcolor(x1grid, x2grid, data[t])
plt.colorbar(pc, label='blublub')
txt = "t = {t:.1f}"
plt.title(txt.format(t = time[t]))
I hope that you understand that, if you want to use a single colormap, you should use a single normalization for all of your plots. That said, here it is your figure with your colormap
And here it's the code
import numpy as np
import matplotlib.pyplot as plt
# Let's fake the data…
Nt, Nxy = 17, 201
x = y = np.linspace(0, 10, Nxy)
x, y = np.meshgrid(x,y)
data = np.empty((Nt, Nxy, Nxy))
for t in range(Nt):
t4 = 1+t/4
data[t] = t4*(1+np.sin( t4*x+y/t4))
# as I said, we need a single normalize object for all the data
norm = plt.Normalize(round(data.min()), round(data.max()))
# now we plot the data's elements
fig = plt.figure(figsize = (8, 8), layout='constrained')
# because we'll later need a list of all axes …
axes = []
for t in range(17):
axes.append(plt.subplot(5, 5, t + 1))
axes[-1].pcolor(x, y, data[t], norm=norm)
axes[-1].set_title('t='+str(t))
# decorate the figure and place the colormap
fig.suptitle('A single colormap, a single normalization scale\n',
size='xx-large')
fig.colorbar(plt.cm.ScalarMappable(norm=norm),
orientation='horizontal',
# ax = axes instructs the colormap to extend over all axes
ax=axes,
# but it's to much, so we shrink it to 75%
shrink=0.75,
# and make it a little slimmer
aspect=30,
)
# I'm satisfied, hence
plt.show()
ps if you want squarish plots, you could a) reduce the figure width or b) play with the aspect of the plots.
I am making multiple plots on the same canvas using data from dataframe. I want to update the plot in a loop based on newly filtered data.
The code I am using is:
from IPython import display
fig = plt.figure(figsize = (10,13))
ax.set_xlim(-0.5,2.5)
ax.set_ylim(-0.5,3.5)
# d_a is a list of dataframes created using different filters
for data_filtered in d_a:
for index,row in data_filtered.iterrows():
x_values = [row['x'] - xy_offset[row['direction']][0]/2.1,
row['x']+xy_offset[row['direction']][0]/2.1]
y_values = [row['y']-xy_offset[row['direction']][1]/2.1,
row['y']+xy_offset[row['direction']][1]/2.1]
# for each row in the dataframe a plot is drawn
plt.plot(x_values,y_values, linewidth=20,color= 'green',
alpha = 0.1
)
t.sleep(0.5)
display.display(plt.gcf())
display.clear_output(wait =True)
Output:(Dynamic and changes with the iteration)
Now the idea is to use a varying value of 'alpha' in the plot based on a certain value in the row of the dataframe.
When I plot this, the opacity just keeps on increasing even when alpha is kept constant as in the code snipped shown.
Shouldn't the display be cleared entirely and a new plot made instead?
You need to clear either the matplotlib axis or figure also, with plt.cla() or plt.clf() respectively. Otherwise the lines will be drawn onto the same matplotlib axis object in memory, and redrawn at each iteration.
from IPython import display
import numpy as np
import time as t
fig = plt.figure(figsize = (10,13))
ax = fig.subplots()
shifts = [1, 3, 4, 1, 2, 5, 2]
for shift in shifts:
ax.plot([0, 1], [0 + shift/10, 1 - shift/10], linewidth=20, color= 'green', alpha = 0.1)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
display.display(plt.gcf())
t.sleep(0.5)
plt.cla()
display.clear_output(wait =True)
I am trying to animate the results of a simulation performed with Python. To do so, I'm using matplotlib to generate the frames of the animation and then I collect them with the Camera class from celluloid library. The code that generates the animation is the following:
fig = plt.figure()
ax = plt.gca()
ax.set_aspect('equal')
camera = Camera(fig)
for i in range(result.t.size):
if i % 10 == 0:
x = result.y[0, i]
y = result.y[1, i]
plt.scatter(x, y, s = 100, c = 'red')
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.grid()
camera.snap()
animation = camera.animate(blit = False, interval = 10)
HTML(animation.to_html5_video())
The last part that generates an HTML5 video allows for watching the animation in a Jupyter notebook on the web. However, I get the following output:
The first output is the corresponding animation, which is working good. The second is just a static empty plot. So I have two questions:
Where does the second plot come from and how can I remove it?
The animation is not showing any grid, though I requested it via plt.grid() on each frame. Why is that happening?
Thanks in advance for any help.
Hi everyone:) I would like to ask for some help to make a class that I can use to plot graphs. i have an excel sheet with different countries and their corresponding air pollution levels. i need to plot graphs for each country. this is the code used to plot my graphs:
import matplotlib.pyplot as plt
import numpy as np
x = df_full_filtered.loc[(df_full_filtered['AirPollutant'] == 'PM10') & (df_full_filtered['Country']
== 'Italy')]['AirPollutionLevel']
plt.style.use('ggplot')
plt.hist(x, bins=80)
plt.show()
y = df_full_filtered.loc[(df_full_filtered['AirPollutant'] == 'PM10') & (df_full_filtered['Country']
== 'Germany')]['AirPollutionLevel']
plt.style.use('ggplot')
plt.hist(y, bins=80)
plt.show()
everytime i run my code, it stops running everytime it reaches the plt.show code and wont continue running till you manually close the popup window with the first graph. is there any way i can surpass this?
edit: i tried putting both codes for x and y under each other and inserting plt.plot(x,y) but they have different shapes (rows/columns in the excel file)
thanks
You need to create two figures.
Method 1
data = [i**2 for i in range(100)]
plt.figure(1)
plt.hist(data, bins = 5)
plt.figure(2)
plt.hist(data, bins = 10)
plt.show()
Method 2
data = [i**2 for i in range(100)]
fig1, ax1 = plt.subplots()
ax1.hist(data, bins = 5)
fig2, ax2 = plt.subplots()
ax2.hist(data, bins = 10)
plt.show()
(If you need, you can call them the same name, i.e. the second figure and axes could be named fig1 and ax1, as well.)
Method 1 is the direct answer to your code. Method 2 is another way of using Matplotlib. (see https://matplotlib.org/matplotblog/posts/pyplot-vs-object-oriented-interface/)
I have two data sets that I would like to produce scatterplots for, with different colors.
Following the advice in MatPlotLib: Multiple datasets on the same scatter plot
I managed to plot them. However, I would like to be able to update the scatter plots inside of a loop that will affect both sets of data. I looked at the matplotlib animation package but it doesn't seem to fit the bill.
I cannot get the plot to update from within a loop.
The structure of the code looks like this:
fig = plt.figure()
ax1 = fig.add_subplot(111)
for g in range(gen):
# some simulation work that affects the data sets
peng_x, peng_y, bear_x, bear_y = generate_plot(population)
ax1.scatter(peng_x, peng_y, color = 'green')
ax1.scatter(bear_x, bear_y, color = 'red')
# this doesn't refresh the plots
Where generate_plot() extracts the relevant plotting information (x,y) coords from a numpy array with additional info and assigns them to the correct data set so they can be colored differently.
I've tried clearing and redrawing but I can't seem to get it to work.
Edit: Slight clarification. What I'm looking to do basically is to animate two scatter plots on the same plot.
Here's a code that might fit your description:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# Create new Figure and an Axes which fills it.
fig = plt.figure(figsize=(7, 7))
ax = fig.add_axes([0, 0, 1, 1], frameon=False)
ax.set_xlim(-1, 1), ax.set_xticks([])
ax.set_ylim(-1, 1), ax.set_yticks([])
# Create data
ndata = 50
data = np.zeros(ndata, dtype=[('peng', float, 2), ('bear', float, 2)])
# Initialize the position of data
data['peng'] = np.random.randn(ndata, 2)
data['bear'] = np.random.randn(ndata, 2)
# Construct the scatter which we will update during animation
scat1 = ax.scatter(data['peng'][:, 0], data['peng'][:, 1], color='green')
scat2 = ax.scatter(data['bear'][:, 0], data['bear'][:, 1], color='red')
def update(frame_number):
# insert results from generate_plot(population) here
data['peng'] = np.random.randn(ndata, 2)
data['bear'] = np.random.randn(ndata, 2)
# Update the scatter collection with the new positions.
scat1.set_offsets(data['peng'])
scat2.set_offsets(data['bear'])
# Construct the animation, using the update function as the animation
# director.
animation = FuncAnimation(fig, update, interval=10)
plt.show()
You might also want to take a look at http://matplotlib.org/examples/animation/rain.html. You can learn more tweaks in animating a scatter plot there.