Generate heat map from a given data set - python

In the following heat map, I want to start y values from 0 to 25. Now it is in the reverse direction.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
import matplotlib
matplotlib.rc('text', usetex=True)
matplotlib.rcParams['text.latex.preamble']=[r"\usepackage{amsmath}"]
a=[]
for i in range(25):
b=[]
for j in range(25):
b.append(i*j)
a.append(b)
fig = plt.figure(figsize=(8,5.00))
plt.imshow(a, interpolation='nearest')
plt.colorbar()
ax = fig.add_subplot(1,1,1)
major_ticks = np.arange(0, 24, 2)
minor_ticks = np.arange(0, 24, 1)
ax.set_xticks(major_ticks)
ax.set_xticks(minor_ticks, minor=True)
plt.xlabel(r'$\pmb{u} \ \longrightarrow$' )
plt.ylabel(r'$\pmb{v} \ \longrightarrow$')
plt.show()
fig.savefig('abc.eps', bbox_inches = 'tight',
pad_inches = 0.2)

Need to include origin='lower'

Related

How do I make a multi panel plot like this?

I have tried using gridspec, everything looks fine but mi main plot doesn't fill all the space.
[1]: https://i.stack.imgur.com/frHEN.png
[2]: https://i.stack.imgur.com/MA1Sg.png
This is my code:
import h5py
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import transforms
from matplotlib.transforms import Affine2D
import matplotlib.gridspec as gridspec
from FUNCION import *
from FUNCIONAVG import *
f = h5py.File('Datos1', 'r')
list(f.keys())
print(f.keys());
data=f['default'];
data=np.array(data)
fig = plt.figure(1, figsize=(5, 5))
gs = gridspec.GridSpec(8, 8)
gs.update(wspace=0, hspace=0)
xtr_subplot = fig.add_subplot(gs[0:6, 0:2])
base = plt.gca().transData
rot = transforms.Affine2D().rotate_deg(90)
line = plt.plot(sum, transform=rot + base)
plt.ylabel("Y Label")
ax = plt.gca()
ax.axes.xaxis.set_ticklabels([])
xtr_subplot = fig.add_subplot(gs[0:6, 2:6])
plt.imshow(data, aspect=(6/4))
ax = plt.gca()
ax.axes.yaxis.set_ticklabels([])
xtr_subplot = fig.add_subplot(gs[6:8, 2:6])
plt.plot(avg)
plt.savefig("multipanel.png")
plt.show()
Set the aspect argument of plt.imshow.
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import gridspec
from matplotlib import transforms
data = np.random.randn(100).reshape(10, 10)
avg = np.random.randn(10)
total = np.random.randn(10)
fig = plt.figure(1, figsize=(5, 5))
gs = gridspec.GridSpec(8, 8)
gs.update(wspace=0, hspace=0)
xtr_subplot = fig.add_subplot(gs[0:6, 0:2])
base = plt.gca().transData
rot = transforms.Affine2D().rotate_deg(90)
line = plt.plot(total, transform=rot + base)
plt.ylabel("Y Label")
ax = plt.gca()
ax.axes.xaxis.set_ticklabels([])
xtr_subplot = fig.add_subplot(gs[0:6, 2:6])
plt.imshow(data, aspect=(6 / 4))
ax = plt.gca()
ax.axes.yaxis.set_ticklabels([])
xtr_subplot = fig.add_subplot(gs[6:8, 2:6])
plt.plot(avg)
plt.savefig("multipanel.png")

Reduce the distance between the numbering on the axis and the ticks

How can I reduce the distance between the numbering of an axis and the ticks corresponding to them. I tried using pad=0 for the tick_params but it doesn't seem to work. Below is a reproducible (simplified) code of my issue (and the figure):
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
plt.rcParams["figure.figsize"] = (10,10)
fig = plt.figure()
ax = Axes3D(fig)
ax.set_xlabel("X" , fontsize=20)
ax.set_ylabel("Y", fontsize=20)
ax.set_zlabel("Z" , fontsize=20)
ax.view_init(azim=-20)
ax.tick_params(axis='x', which='major', pad=0)
x = np.arange(0,10,0.01)
y = np.ones(len(x))
z = np.sin(x)
plt.plot(x,y,z)
Changing the values of pad seem to not have any effect. Note: I need the plot in that specific orientation (azim=-20). How can I achieve what I need? Thank you!
The pad argument also takes negative values to bring the ticklabels closer to the ticks.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
fig = plt.figure()
ax = axes3d.Axes3D(fig)
ax.set_xlabel("X" , fontsize=20)
ax.set_ylabel("Y", fontsize=20)
ax.set_zlabel("Z" , fontsize=20)
ax.view_init(azim=-20)
ax.tick_params(axis='x', which='major', pad=-5)
x = np.arange(0, 10, 0.01)
y = np.ones(len(x))
z = np.sin(x)
plt.plot(x, y, z)
plt.show()
EDIT: Alternative outcome with set figure size and dpi value.
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
mpl.rcParams["figure.figsize"] = 10, 10
mpl.rcParams["figure.dpi"] = 100
fig = plt.figure()
ax = axes3d.Axes3D(fig)
ax.set_xlabel("X" , fontsize=20)
ax.set_ylabel("Y", fontsize=20)
ax.set_zlabel("Z" , fontsize=20)
ax.view_init(azim=-20)
ax.tick_params(axis='x', which='major', pad=-5)
x = np.arange(0, 10, 0.01)
y = np.ones(len(x))
z = np.sin(x)
plt.plot(x, y, z)
plt.show()

Aligning x-axis with sharex using subplots and colorbar with matplotlib

I'm trying to create a set of subplots with a shared x axis using pyplot. This is all fine and dandy when the graphs are simple and all the x-axes align fine. However when I include a subplot that includes a colorbar, this compresses the width of that particular subplot to include the colorbar, resulting in the subplots no longer sharing the x-axis.
I've searched the web with no success with this. I've tried several different methods, but the simplest example I include below. I plot the exact same data in each subplot, but plot one with a colorbar. You can see the data no longer align along the x-axis.
Thanks in advance for your help!
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
import pandas as pd
x = np.linspace(0, 10, num=100)
y = x ** 2 + 10 * np.random.randn(100)
f, (ax1, ax2) = plt.subplots(2,1,sharex=True,figsize=(8,12))
im1 = ax1.scatter(x, y, c=y, cmap='magma')
divider = make_axes_locatable(ax1)
cax = divider.append_axes("right", size="5%", pad=.05)
plt.colorbar(im1, cax=cax)
im2 = ax2.plot(x, y,'.')
plt.show()
Suggest using constrained_layout=True: https://matplotlib.org/stable/tutorials/intermediate/constrainedlayout_guide.html
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, num=100)
y = x ** 2 + 10 * np.random.randn(100)
f, (ax1, ax2) = plt.subplots(2,1,sharex=True,figsize=(8,12),
constrained_layout=True)
im1 = ax1.scatter(x, y, c=y, cmap='magma')
f.colorbar(im1, ax=ax1)
im2 = ax2.plot(x, y,'.')
This is one hacky way to do it.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
import pandas as pd
x = np.linspace(0, 10, num=100)
y = x ** 2 + 10 * np.random.randn(100)
f, (ax1, ax2) = plt.subplots(2,1,sharex=True,figsize=(8,12))
im1 = ax1.scatter(x, y, c=y, cmap='magma')
divider = make_axes_locatable(ax1)
cax = divider.append_axes("right", size="5%", pad=.05)
plt.colorbar(im1, cax=cax)
im2 = ax2.plot(x, y,'.')
divider2 = make_axes_locatable(ax2)
cax2 = divider2.append_axes("right", size="5%", pad=.05)
cax2.remove()
plt.show()
results in
You can account for the needed with of the colorbar already when you create the subplots. Instead of using the divider, generate four subplots with different widths using gridspec_kw. You can then delete the unneeded cax for the second subplot:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, num=100)
y = x ** 2 + 10 * np.random.randn(100)
##creating four subplots with unequally divided widths:
f, axes = plt.subplots(
2,2, sharex='col', figsize=(8,12),
gridspec_kw = {'width_ratios' : (10,1)},
)
ax1,ax2 = axes[:,0]
##remove unneeded Axes instance:
axes[1,1].remove()
im1 = ax1.scatter(x, y, c=y, cmap='magma')
plt.colorbar(im1, cax=axes[0,1])
im2 = ax2.plot(x, y,'.')
f.savefig('sharex_colorbar.png')
The result looks like this:
As an alternative to deleting the unneded subplot instances, you can also first generate the gridspec explicitly and generate only the needed subplots. This might be more suitable if you have many plots:
from matplotlib.gridspec import GridSpec
gs = GridSpec(nrows=2, ncols=2, width_ratios = (10,1))
f = plt.figure(figsize=(8,12))
ax1 = f.add_subplot(gs[0,0])
ax2 = f.add_subplot(gs[1,0],sharex=ax1)
cax = f.add_subplot(gs[0,1])
im1 = ax1.scatter(x, y, c=y, cmap='magma')
plt.colorbar(im1, cax=cax)

Matplotlib : the colorbar keeps shrinking

I wrote a code where I have an array called array2 with numbers between 0. and 1. in it. When I click on the array displayed by imshow the cells in the array take the value 2. and become red.
Then I added a colorbar but it kept shrinking once I clicked on it and the cells didn't become red.
What am I doing wrong ?
Code without colorbar (works fine)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib import cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from random import random
def test(n):
array1 = np.zeros((n,n))
for i in range(n):
for j in range(n):
array1[i,j] = random()
return array1
# Array
global array2
array2 = test(10)
# Colormap
greens = cm.Greens(np.linspace(0,1, num=50))
greensfill = cm.Greens(np.ones(25))
red = [(1,0,0,1)]*len(greens)
gray = [(.5,.5,.5,1)]*len(greens)
colors = np.vstack((greens, greensfill, red, gray))
mycmap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
# Matplotlib
fig, axes = plt.subplots(1)
fig.tight_layout()
plt.imshow(array2, animated=True, cmap = mycmap, interpolation="none", vmin=0, vmax=3.5, origin='lower')
def onclick(event):
global x, y
x, y = int(event.xdata), int(event.ydata)
array2[y,x] = 2.
plt.imshow(array2, animated=True, cmap = mycmap, interpolation="none", vmin=0, vmax=3.5, origin='lower')
fig.canvas.mpl_connect('button_press_event', onclick)
Code with colorbar (doesn't work)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib import cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from random import random
def test(n):
array1 = np.zeros((n,n))
for i in range(n):
for j in range(n):
array1[i,j] = random()
return array1
# Array
global array2
array2 = test(10)
# Colormap
greens = cm.Greens(np.linspace(0,1, num=50))
greensfill = cm.Greens(np.ones(25))
red = [(1,0,0,1)]*len(greens)
gray = [(.5,.5,.5,1)]*len(greens)
colors = np.vstack((greens, greensfill, red, gray))
mycmap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
# Matplotlib
fig, axes = plt.subplots(1)
fig.tight_layout()
im = plt.imshow(array2, animated=True, cmap = mycmap, interpolation="none", vmin=0, vmax=3.5, origin='lower')
divider = make_axes_locatable(axes)
cax = divider.append_axes("right", size="13%", pad=0.2)
cb = plt.colorbar(im, cax=cax, boundaries=np.linspace(0,1, num=100), ticks=[0,1])
cb.set_label("Title", fontsize=15, labelpad=-5, y=0.5)
def onclick(event):
global x, y
x, y = int(event.xdata), int(event.ydata)
array2[y,x] = 2.
im = plt.imshow(array2, animated=True, cmap = mycmap, interpolation="none", vmin=0, vmax=3.5, origin='lower')
divider = make_axes_locatable(axes)
cax = divider.append_axes("right", size="13%", pad=0.2)
cb = plt.colorbar(im, cax=cax, boundaries=np.linspace(0,1, num=100), ticks=[0,1])
cb.set_label("Title", fontsize=15, labelpad=-5, y=0.5)
fig.canvas.mpl_connect('button_press_event', onclick)
It would be better to just update the imshow, instead of drawing a new one every time a click is performed. This can be done using the .set_data() method. The advantage is that the colorbar can stay where it is and doesn't get touched.
In general it's best to work with the plotting objects directly instead of pyplot when doing interactive stuff. So using fig and ax instead of plt in most cases.
Note that to accurately catch the click on a pixel you need to round the coordinate first, int(np.round(event.xdata)).
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib import cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
global array2
array2 = np.random.rand(10,10)
# Colormap
greens = cm.Greens(np.linspace(0,1, num=50))
greensfill = cm.Greens(np.ones(25))
red = [(1,0,0,1)]*len(greens)
gray = [(.5,.5,.5,1)]*len(greens)
colors = np.vstack((greens, greensfill, red, gray))
mycmap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
# Matplotlib
fig, ax = plt.subplots()
fig.tight_layout()
im = ax.imshow(array2, animated=True, cmap = mycmap, interpolation="none",
vmin=0, vmax=3.5, origin='lower')
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="13%", pad=0.2)
cb = fig.colorbar(im, ax =ax, cax=cax, boundaries=np.linspace(0,1, num=100),
ticks=[0,1])
cb.set_label("Title", fontsize=15, labelpad=-5, y=0.5)
def onclick(event):
x, y = int(np.round(event.xdata)), int(np.round(event.ydata))
array2[y,x] = 2.
im.set_data(array2)
fig.canvas.draw_idle()
fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()

How to make a 3D scatter plot in matplotlib

I am currently have a nx3 matrix array. I want plot the three columns as three axis's.
How can I do that?
I have googled and people suggested using Matlab, but I am really having a hard time with understanding it. I also need it be a scatter plot.
Can someone teach me?
You can use matplotlib for this. matplotlib has a mplot3d module that will do exactly what you want.
import matplotlib.pyplot as plt
import random
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(projection='3d')
sequence_containing_x_vals = list(range(0, 100))
sequence_containing_y_vals = list(range(0, 100))
sequence_containing_z_vals = list(range(0, 100))
random.shuffle(sequence_containing_x_vals)
random.shuffle(sequence_containing_y_vals)
random.shuffle(sequence_containing_z_vals)
ax.scatter(sequence_containing_x_vals, sequence_containing_y_vals, sequence_containing_z_vals)
plt.show()
The code above generates a figure like:
Use the following code it worked for me:
# Create the figure
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Generate the values
x_vals = X_iso[:, 0:1]
y_vals = X_iso[:, 1:2]
z_vals = X_iso[:, 2:3]
# Plot the values
ax.scatter(x_vals, y_vals, z_vals, c = 'b', marker='o')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')
plt.show()
while X_iso is my 3-D array and for X_vals, Y_vals, Z_vals I copied/used 1 column/axis from that array and assigned to those variables/arrays respectively.
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = plt.axes(projection='3d')
scatter plot
zdata = 15 * np.random.random(100)
xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
ax.scatter3D(xdata, ydata, zdata);
Colab notebook
Using plotly - Easiest and most functional and nice plots
import plotly.express as px
df = px.data.iris()
fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',
color='species')
fig.show()
https://plotly.com/python/3d-scatter-plots/

Categories