Python How to set axes for a matplotlib plot - python

Hi for the matplotlib plot below I want to set the axes titles such that they show that the x-axis values run from
2**-5, 2**-4, 2**-3,..., 2**14, 2**15
and the y-axis values run from
2**-15, 2**-14,...., 2**4, 2**5
The graph I want to display them on is:
The code for the graph is below:
from matplotlib import pyplot
import matplotlib as mpl
import numpy as np
zvals = 100*np.random.randn(21, 21)
fig = pyplot.figure(2)
cmap2 = mpl.colors.LinearSegmentedColormap.from_list('my_colormap',
['blue','green','brown'],
256)
img2 = pyplot.imshow(zvals,interpolation='nearest',
cmap = cmap2,
origin='lower')
pyplot.colorbar(img2,cmap=cmap2)
pyplot.show()

You can use a range with a stepsize to label every 5th cell:
locs = range(0, N, 5)
ax.set(xticks=locs, xlabels=...)
For example,
from matplotlib import pyplot as plt
from matplotlib import colors as mcolors
import numpy as np
N = 21
zvals = 100*np.random.randn(N, N)
fig = plt.figure(2)
ax = fig.add_subplot(111)
cmap2 = mcolors.LinearSegmentedColormap.from_list(
'my_colormap', ['blue','green','brown'], 256)
img2 = plt.imshow(zvals,interpolation='nearest',
cmap=cmap2, origin='lower')
plt.colorbar(img2, cmap=cmap2)
step = 5
locs = range(0, N, step)
ax.set(
xticks=locs,
xticklabels=['$2^{{{}}}$'.format(i-5) for i in locs],
yticks=locs,
yticklabels=['$2^{{{}}}$'.format(i-15) for i in locs])
plt.show()

Related

Scale y-axis for really small numbers

I'm trying to scale the y-axis so my errorbars can be seen.
Any help would be appreciated! :)
Here is my current code.
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
# if using a Jupyter notebook, include:
%matplotlib inline
x = ntermsList
y = allPmuCycleCountAverages
xerr = 0
yerr = allPmuCycleCountStandardDeviations
fig, ax = plt.subplots()
ax.errorbar(x, y, xerr=xerr, yerr=yerr,fmt='-o')
ax.set_xlabel('x-axis')
ax.set_ylabel('y-axis')
ax.set_title('Line plot with error bars')
ax.set_xticks(ntermsList)
ax.set_xticklabels(ntermsList)
ax.set_yticks(allPmuCycleCountAverages)
ax.yaxis.grid(True)
plt.show()
I've tried these solutions, but no joy:
plt.ylim(-1, 1)
plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True
plt.yticks(np.arange(min(y), max(y)+0.5, 0.01))
I was expecting the y-axis scale to zoom close enough to the points so my errorbars could be seen
Try autoscalling based in y ticks. Here I'm adding some logic that just rescales the y-axis based on the data that is in the visible x-region. As I don't have your data I took random data.
import numpy as np
import random
ntermsList = np.random.randint(low=0, high=10, size=(555,))
allPmuCycleCountAverages = np.random.randint(low=0, high=10, size=(555,))
allPmuCycleCountStandardDeviations = np.random.randint(low=0, high=10, size=(555,))
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
# if using a Jupyter notebook, include:
%matplotlib inline
x = ntermsList
y = allPmuCycleCountAverages
xerr = 0
yerr = allPmuCycleCountStandardDeviations
fig, ax = plt.subplots()
ax.errorbar(x, y, xerr=xerr, yerr=yerr,fmt='-o')
ax.set_xlabel('x-axis')
ax.set_ylabel('y-axis')
ax.set_title('Line plot with error bars')
ax.set_xticks(ntermsList)
ax.set_xticklabels(ntermsList)
ax.set_yticks(allPmuCycleCountAverages)
#plt.setp(ax.get_yticklabels(), rotation=90, horizontalalignment='right')
ax.yaxis.grid(True)
margin =0.1
def get_bottom_top(line):
xd = line.get_xdata()
yd = line.get_ydata()
lo,hi = ax.get_xlim()
y_displayed = yd[((xd>lo) & (xd<hi))]
h = np.max(y_displayed) - np.min(y_displayed)
bot = np.min(y_displayed)-margin*h
top = np.max(y_displayed)+margin*h
return bot,top
lines = ax.get_lines()
bot,top = np.inf, -np.inf
for line in lines:
new_bot, new_top = get_bottom_top(line)
if new_bot < bot: bot = new_bot
if new_top > top: top = new_top
ax.set_ylim(bot,top)
plt.show()
Before Rescalling
After rescalling

Fading animated scatterplot with multiple colours

I have 3 columns of data representing 3 pixels (x1, x2, x3), that update live.
I want to:
animate a scatter with x1 at x=1, x2 at x=2, x3 at x=3
have a distinct colour for each of the pixels (x1=red, x2=blue, x3=green)
when updating the figure with new data, have previous scatter data fade.
I am trying to modify from: Matplotlib Plot Points Over Time Where Old Points Fade
However I am unable to assign a different colour to each value of x (x=1, x=2, x=3):
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.animation import PillowWriter
fig, ax = plt.subplots()
ax.set_xlabel('X Axis', size = 12)
ax.set_ylabel('Y Axis', size = 12)
ax.axis([0,4,0,1])
x_vals = []
y_vals = []
intensity = []
iterations = 100
t_vals = np.linspace(0,1, iterations)
colors = [[0,0,1,0],[0,0,1,0.5],[0,0.2,0.4,1], [1,0.2,0.4,1]]
cmap = LinearSegmentedColormap.from_list("", colors)
scatter = ax.scatter(x_vals,y_vals, c=[], cmap=cmap, vmin=0,vmax=1)
def get_new_vals():
x = np.arange(1,4) # TODO: ASSOCIATE COLOUR WITH EACH X VALUE
y = np.random.rand(3)
return list(x), list(y)
def update(t):
global x_vals, y_vals, intensity
# Get intermediate points
new_xvals, new_yvals = get_new_vals()
x_vals.extend(new_xvals)
y_vals.extend(new_yvals)
# Put new values in your plot
scatter.set_offsets(np.c_[x_vals,y_vals])
#calculate new color values
intensity = np.concatenate((np.array(intensity)*0.96, np.ones(len(new_xvals))))
scatter.set_array(intensity)
# Set title
ax.set_title('Different colours for each x value')
ani = matplotlib.animation.FuncAnimation(fig, update, frames=t_vals,interval=50)
plt.show()
It looks like you took the right approach, the only change I would suggest is creating 3 different scatter plots (one for each x values) instead of one.
See code below:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.animation import PillowWriter
import matplotlib.cm as cm
fig, ax = plt.subplots()
ax.set_xlabel('X Axis', size = 12)
ax.set_ylabel('Y Axis', size = 12)
ax.axis([0,4,0,1])
x_vals = []
y_vals = []
iterations = 100
t_vals = np.linspace(0,1, iterations)
cmaps=[cm.get_cmap('Reds'),cm.get_cmap('Blues'),cm.get_cmap('Greens')] #declaring colormaps
scatters=[ax.scatter(x_vals,y_vals,c=[],cmap=cmaps[i],vmin=0,vmax=1) for i in range(len(cmaps))] #initializing the 3 scatter plots
intensities=[[] for i in range(len(cmaps))] #initializing intensities array
def get_new_vals():
x = np.arange(1,4)
y = np.random.rand(3)
return x,y
def update(t):
global x_vals, y_vals, intensities
# Get intermediate points
new_xvals, new_yvals = get_new_vals()
x_vals=np.hstack((x_vals,new_xvals))
y_vals=np.hstack((y_vals,new_yvals))
# Put new values in your plot
for i in range(3):
scatters[i].set_offsets(np.c_[x_vals[x_vals==i+1],y_vals[x_vals==i+1]])
intensities[i]=np.concatenate((np.array(intensities[i])*0.96, np.ones(len(new_xvals[new_xvals==i+1]))))
scatters[i].set_array(intensities[i])
ax.set_title('Different colours for each x value')
ani = matplotlib.animation.FuncAnimation(fig, update, frames=t_vals,interval=50)
plt.show()

limit range of colorbar on bar graph in matplotlib

I've been attempting to limit the range on the colorbar function in matplotlib. For whatever reason, I cannot use the clim function. Ideally I would like 80 and 20 to be the max values of the colorbar, and all values above or below those values to be a single dark blue/red, and the entire colorbar to be fit within the range of 20 and 80.
import requests
from bs4 import BeautifulSoup
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
import matplotlib as mpl
import numpy as np
Gpercent=40
xGpercent = 60
SCFpercent = 55
CFpercent = 45
Analytics = ['GF%','xGF%','SCF%','CF%']
AnalyticsValues = [Gpercent,xGpercent,SCFpercent,CFpercent]
AnalyticsValues = [float(val) for val in AnalyticsValues]
data_height_normalized = [x / 100 for x in AnalyticsValues]
fig, ax = plt.subplots(figsize=(15, 4))
#my_cmap = plt.cm.get_cmap('RdBu')
my_cmap = plt.cm.get_cmap('coolwarm_r')
colors = my_cmap(data_height_normalized)
rects = ax.bar(Analytics, AnalyticsValues, color=colors)
sm = ScalarMappable(cmap=my_cmap, norm=plt.Normalize(0,100))
plt.ylim(0, 100)
cbar = plt.colorbar(sm)
plt.yticks(np.arange(0, 100.8, 10))
plt.title('bob' + (" On Ice 5v5 Impact"))
plt.xlabel('Analytical Metric')
plt.ylabel('%')
fig.patch.set_facecolor('xkcd:white')
plt.show()
The plot comes out as follows. I'd like the colorbar to be more defined in a shorter range, while still showing the % from 0-100
The intent of your question is to add an upper and lower limit to the color bar only. I would like to set the lower limit to 20 and the upper limit to 80. I will answer with the understanding that
The gist of the code is to create a new colormap from the defined colormap using LinearSegmentedColormap with the upper and lower color range.
My answer was modified from this excellent answer to fit your assignment.
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
from matplotlib.colors import LinearSegmentedColormap # add
import matplotlib as mpl
import numpy as np
Gpercent=40
xGpercent = 60
SCFpercent = 55
CFpercent = 45
Analytics = ['GF%','xGF%','SCF%','CF%']
AnalyticsValues = [Gpercent,xGpercent,SCFpercent,CFpercent]
AnalyticsValues = [float(val) for val in AnalyticsValues]
data_height_normalized = [x / 100 for x in AnalyticsValues]
fig, ax = plt.subplots(figsize=(15, 4))
#my_cmap = plt.cm.get_cmap('RdBu')
my_cmap = plt.cm.get_cmap('coolwarm_r')
colors = my_cmap(data_height_normalized)
rects = ax.bar(Analytics, AnalyticsValues, color=colors)
# update
vmin,vmax = 20,80
colors2 = my_cmap(np.linspace(1.-(vmax-vmin)/float(vmax), 1, my_cmap.N))
color_map = LinearSegmentedColormap.from_list('cut_coolwarm', colors2)
sm = ScalarMappable(cmap=color_map, norm=plt.Normalize(vmin, vmax))
plt.ylim(0, 100)
cbar = plt.colorbar(sm)
plt.yticks(np.arange(0, 100.8, 10))
plt.title('bob' + (" On Ice 5v5 Impact"))
plt.xlabel('Analytical Metric')
plt.ylabel('%')
fig.patch.set_facecolor('xkcd:white')
plt.show()

How to rescale a plot in a subplot with matplotlib

I have 4 subplots with a different 3D plot with a colorbar.
I want to plot a XY view of my 3D plot, remove the x,y,z axis and resize my plot to use all the space available in the subplot such that the XY view has the same height as the colorbar. I can remove the axis but I do not know how to resize the image. I attached a working code to illustrate this.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib
import numpy as np
# Create 3D function
n_radii = 8
n_angles = 36
radii = np.linspace(0.125, 1.0, n_radii)
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)[..., np.newaxis]
x = np.append(0, (radii*np.cos(angles)).flatten())
y = np.append(0, (radii*np.sin(angles)).flatten())
z = np.sin(-x*y)
fig = plt.figure()
for ii in range(1, 4):
#Plot
# ============================================================================
ax = fig.add_subplot(2,2, ii, projection='3d')
cs =ax.plot_trisurf(x, y, z, linewidth=0.2, antialiased=True)
ax.view_init(90, 0)
plt.title(ii)
# ax.axis('off')
plt.grid(b=None)
# Create color bar
# ============================================================================
norm = matplotlib.colors.Normalize(vmin = 0, vmax = 1, clip = False)
m = plt.cm.ScalarMappable(norm=norm)
m.set_array([])
plt.colorbar(m)
plt.tight_layout()
plt.show()
#plt.savefig("test.pdf",bbox_inches='tight')
Any idea how can I do this?
I have added
plt.gca().set_axis_off()
plt.axis([0.6 * x for x in plt.axis()])
to your code which hides the axes and sets the view to 60% of its previous value. The result looks like this:
Full code:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib
import numpy as np
# Create 3D function
n_radii = 8
n_angles = 36
radii = np.linspace(0.125, 1.0, n_radii)
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)[..., np.newaxis]
x = np.append(0, (radii*np.cos(angles)).flatten())
y = np.append(0, (radii*np.sin(angles)).flatten())
z = np.sin(-x*y)
fig = plt.figure()
for ii in range(1, 4):
#Plot
# ============================================================================
ax = fig.add_subplot(2,2, ii, projection='3d')
cs =ax.plot_trisurf(x, y, z, linewidth=0.2, antialiased=True)
ax.view_init(90, 0)
plt.title(ii)
# ax.axis('off')
plt.grid(b=None)
# Create color bar
# ============================================================================
norm = matplotlib.colors.Normalize(vmin = 0, vmax = 1, clip = False)
m = plt.cm.ScalarMappable(norm=norm)
m.set_array([])
plt.colorbar(m)
plt.gca().set_axis_off()
plt.axis([0.6 * x for x in plt.axis()])
plt.tight_layout()
plt.show()
#plt.savefig("test.pdf",bbox_inches='tight')

matplotlib hist() autocropping range

I am trying to make a histgram over a specific range but the matplotlib.pyplot.hist() function keeps cropping the range to the bins with entries in them. A toy example:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(-100,100,1000)
nbins = 100
xmin = -500
xmax = 500
fig = plt.figure();
ax = fig.add_subplot(1, 1, 1)
ax.hist(x, bins=nbins,range=[xmin,xmax])
plt.show()
Gives a plot with a range [-100,100]. Why is the range not [-500,500] as specified?
(I am using the Enthought Canopy 1.4 and sorry but I do not have a high enough rep to post an image of the plot.)
Actually, it works if you specify with range an interval shorter than [-100, 100]. For example, this work :
import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(-100, 100, 1000)
plt.hist(x, bins=30, range=(-50, 50))
plt.show()
If you want to plot the histogram on a range larger than [x.min(), x.max()] you can change xlim propertie of the plot.
import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(-100, 100, 1000)
plt.hist(x, bins=30)
plt.xlim(-500, 500)
plt.show()
the following code is for making the same y axis limit on two subplots
f ,ax = plt.subplots(1,2,figsize = (30, 13),gridspec_kw={'width_ratios': [5, 1]})
df.plot(ax = ax[0], linewidth = 2.5)
ylim = [df['min_return'].min()*1.1,df['max_return'].max()*1.1]
ax[0].set_ylim(ylim)
ax[1].hist(data,normed =1, bins = num_bin, color = 'yellow' ,alpha = 1)
ax[1].set_ylim(ylim)

Categories