Here is a code to plot an animation with blit enabled.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
def update_fig(num, data, plot, ax) :
text = None
if num % 2 == 0 :
text = ax.text(0.5, 0.5, str(num), horizontalalignment='center', verticalalignment='center', transform=ax.transAxes,size=15)
plot.set_array(data[:, :, num %1500].ravel())
if text :
return pp_color, text,
else :
return pp_color,
fig, ax = plt.subplots()
data = np.random.rand(60, 50, 1500)
pp_color = plt.pcolormesh(data[:,:, 0], cmap = 'Reds', vmin=np.amin(data), vmax=np.amax(data))
cbar = plt.colorbar()
t1 = cbar.ax.set_title('t1')
plt.axis('equal')
ax.text(0.5, -0.1, 'footnote text', horizontalalignment='center', transform=ax.transAxes,)
t2 = ax.set_title("t2")
line_ani = animation.FuncAnimation(fig, update_fig,
interval=0.1, blit=True, fargs=(data, pp_color, ax))
plt.show()
When I run the script I get that :
I have to resize my window to have title, colorbar displayed.
When I comment animation code, first figure frame is correctly displayed.
How can I correctly display my figure without resizing it?
Related
Im trying to make a plot with a slider to adjust the variables to visualize changes in lines.
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
x = list(range(0,11))
y = [10] * 11
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.1, bottom=0.35)
p, =plt.plot(x,y, linewidth=2, color='blue')
plt.axis([0,10, 0, 100])
axSlider1 = plt.axes([0.1,0.2, 0.8, 0.05])
slder1 = Slider(axSlider1, 'Slider 1', valmin=0, valmax=100)
axSlider2 =plt.axes([0.1,0.1, 0.8, 0.05])
slder2 = Slider( ax=axSlider2,
label='Slider2',
valmin=0,
valmax=100,
valinit=30,
valfmt='%1.2f',
closedmax=False)
i used this code and itll plot perfectly but i cant slide the slider in colab.
I have a simple plot, where I want to insert image of UAV, but it doesn't show up. I believe that the annotation box is somewhere out of area of plot, but can't figure out where to move it. Currently I want to have it at [2,4], just to test.
Here is my code:
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
import random
from matplotlib.offsetbox import (OffsetImage, AnnotationBbox)
import matplotlib.image as image
fig = plt.figure()
ax = plt.axes(projection="3d")
num_bars = 3
x_pos = random.sample(range(20), num_bars)
y_pos = random.sample(range(20), num_bars)
z_pos = [0] * num_bars
x_size = np.ones(num_bars)
y_size = np.ones(num_bars)
z_size = random.sample(range(20), num_bars)
#ax.bar3d(x_pos, y_pos, z_pos, x_size, y_size, z_size, color='grey')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_xlim(0,20)
ax.set_ylim(0,20)
ax.set_zlim(0,30)
"""
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
"""
img="./UAV.png"
uav = image.imread(img)
arr_img = plt.imread("./UAV.png", format='png')
imagebox = OffsetImage(arr_img, zoom = .15)
imagebox.image.axes = ax
#ab = AnnotationBbox(imagebox, (5, 10), xybox = (5.0, 10.0), box_alignment=(1, 0))
ab = AnnotationBbox(imagebox, [2., 4.],
xycoords='data',
boxcoords="offset points",
pad=0
)
ax.add_artist(ab)
ax.bar3d(0,0,0,4,4,25,color="grey")
ax.bar3d(16,16,0,4,4,27,color="grey")
ax.bar3d(0,16,0,4,4,23,color="grey")
plt.tight_layout()
plt.show()
I could not find the problem with annotation box, but I have managed to fix this by adding the image to the plot by imshow instead. See the code:
arr_img = plt.imread("./UAV.png", format='png')
newax = fig.add_axes([0.45,0.5,0.2,0.2], anchor='NE', zorder=1)
newax.imshow(arr_img)
newax.patch.set_alpha(0.01)
newax.get_xaxis().set_ticks([])
newax.get_yaxis().set_ticks([])
newax.spines['top'].set_visible(False)
newax.spines['right'].set_visible(False)
newax.spines['bottom'].set_visible(False)
newax.spines['left'].set_visible(False)
output:
I want to plot an image with pyplot and on top of that image a point.
That point is from an input field in the pyplot. Here I have a piece of code, where you can put a point in, but after pressing enter, or search button it won't plot the point. Here is my code:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import TextBox
def imshow_rgb(img_bgr):
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
plt.imshow(img_rgb)
ims = cv2.imread('plattegrondtekening.png', 1)
fig = plt.imshow(np.flipud(ims), cmap='gray', origin='lower')
plt.subplots_adjust(bottom=0.2)
initial_text = ""
x,y=[500,500]
def submit(text):
x,y = list(map(int,text.split(",")))
print(x,y)
plt.plot(x, y, "ro")
plt.show()
axbox = plt.axes([0.1, 0.05, 0.8, 0.075])
text_box = TextBox(axbox, 'search', initial=initial_text)
text_box.on_submit(submit)
plt.show()
image plot with input field below, this is the output of the code above
But I want that it shows a point on x=900 and y=800, when I enter 900,800 in the input box.
We have to select the active axes first using plt.sca(ax) and for refreshing the canvas we may use fig.canvas.draw() and fig.canvas.flush_events().
Replace fig = plt.imshow(np.flipud(ims), cmap='gray', origin='lower') with:
fig = plt.figure() # Keep the figure for later usage.
ax = plt.gca() # Keep the axes for later usage.
ax.imshow(np.flipud(ims), cmap='gray', origin='lower') # Show the image on axes ax
Replace plt.plot(x, y, "ro") and plt.show() with:
plt.sca(ax) # Set active axes
plt.plot(x, y, "ro")
fig.canvas.draw() # Refresh the canvas.
fig.canvas.flush_events()
Code sample:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import TextBox
ims = cv2.imread('plattegrondtekening.png', 1)
fig = plt.figure() # Keep fig for later usage
ax = plt.gca() # https://stackoverflow.com/questions/25505341/how-to-get-the-axesimages-from-matplotlib
ax.imshow(np.flipud(ims), cmap='gray', origin='lower')
plt.subplots_adjust(bottom=0.2)
initial_text = ""
x,y=[500,500]
def submit(text):
x, y = list(map(int,text.split(",")))
print(x,y)
plt.sca(ax) # https://stackoverflow.com/questions/19625563/matplotlib-change-the-current-axis-instance-i-e-gca
plt.plot(x, y, "ro")
fig.canvas.draw() # https://stackoverflow.com/questions/4098131/how-to-update-a-plot-in-matplotlib
fig.canvas.flush_events()
axbox = plt.axes([0.1, 0.05, 0.8, 0.075])
text_box = TextBox(axbox, 'search', initial=initial_text)
text_box.on_submit(submit)
plt.show()
here is my update plot program which I want to put into a pyqt5 window.
I can't find any examples which use the _update_plot function they all use update_figure or a draw function with a timer whereas mine uses an i variable that updates at specified rate.
Any help/advice is appreciated
program:
import math
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
from matplotlib.widgets import Slider, Button, RadioButtons
from matplotlib import style
style.use('seaborn-poster')
def _update_plot(i, fig, scat, l,l2):
M = ((math.sin(math.radians(i))*7.5)-(math.sin(math.radians(i/2))*9))/((math.cos(math.radians(i))*7.5)-(math.cos(math.radians(i/2))*9))
g = M*(15-(math.cos(math.radians(i/2))*9))+(math.sin(math.radians(i/2))*9)
scat.set_offsets(([math.cos(math.radians(i))*7.5, math.sin(math.radians(i))*7.5], [math.cos(math.radians(i/2))*9, math.sin(math.radians(i/2))*9], [0, 0]))
if (i>=540) or (i<=180):
l.set_data(([math.cos(math.radians(i))*7.5,math.cos(math.radians(i/2))*9],[math.sin(math.radians(i))*7.5,math.sin(math.radians(i/2))*9]))
l2.set_data(([math.cos(math.radians(i/2))*9,15],[math.sin(math.radians(i/2))*9,g]))
else:
l.set_data(([0,0],[0,0]))
l2.set_data(([0,0],[0,0]))
return [scat,l,l2]
fig = plt.figure()
x = [0]
y = [0]
ax = fig.add_subplot(111)
ax.set_aspect('equal')
ax.grid(True, linestyle = '-', color = '0.10')
ax.set_xlim([-15, 15])
ax.set_ylim([-15, 15])
l, = plt.plot([],[], '-', zorder=1)
l2, = plt.plot([],[], '-', zorder=2)
scat = plt.scatter(x, y, c = x, zorder=3)
scat.set_alpha(0.8)
anim = animation.FuncAnimation(fig, _update_plot, fargs = (fig, scat, l,l2),
frames = 720, interval = 10)
plt.show()
I'd like to create a colorbar legend for a heatmap, such that the labels are in the center of each discrete color. Example borrowed from here:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
#discrete color scheme
cMap = ListedColormap(['white', 'green', 'blue','red'])
#data
np.random.seed(42)
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=cMap)
#legend
cbar = plt.colorbar(heatmap)
cbar.ax.set_yticklabels(['0','1','2','>3'])
cbar.set_label('# of contacts', rotation=270)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
ax.invert_yaxis()
#labels
column_labels = list('ABCD')
row_labels = list('WXYZ')
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
This generates the following plot:
Ideally I'd like to generate a legend bar which has the four colors and for each color, a label in its center: 0,1,2,>3. How can this be achieved?
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
#discrete color scheme
cMap = ListedColormap(['white', 'green', 'blue','red'])
#data
np.random.seed(42)
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=cMap)
#legend
cbar = plt.colorbar(heatmap)
cbar.ax.get_yaxis().set_ticks([])
for j, lab in enumerate(['$0$','$1$','$2$','$>3$']):
cbar.ax.text(.5, (2 * j + 1) / 8.0, lab, ha='center', va='center')
cbar.ax.get_yaxis().labelpad = 15
cbar.ax.set_ylabel('# of contacts', rotation=270)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
ax.invert_yaxis()
#labels
column_labels = list('ABCD')
row_labels = list('WXYZ')
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
You were very close. Once you have a reference to the color bar axis, you can do what ever you want to it, including putting text labels in the middle. You might want to play with the formatting to make it more visible.
To add to tacaswell's answer, the colorbar() function has an optional cax input you can use to pass an axis on which the colorbar should be drawn. If you are using that input, you can directly set a label using that axis.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
divider = make_axes_locatable(ax)
cax = divider.append_axes('bottom', size='10%', pad=0.6)
cb = fig.colorbar(heatmap, cax=cax, orientation='horizontal')
cax.set_xlabel('data label') # cax == cb.ax
This will make you add label and change colorbar's tick and label size:
clb=plt.colorbar()
clb.ax.tick_params(labelsize=8)
clb.ax.set_title('Your Label',fontsize=8)
This can be also used if you have sublots:
plt.tight_layout()
plt.subplots_adjust(bottom=0.05)
cax = plt.axes([0.1, 0, 0.8, 0.01]) #Left,bottom, length, width
clb=plt.colorbar(cax=cax,orientation="horizontal")
clb.ax.tick_params(labelsize=8)
clb.ax.set_title('Your Label',fontsize=8)