How to modify a title Matplotlib - python-3.x

How could I edit the second row of my title to be a smaller font and normal weight? Also, how could I adjust the padding between the title and the plot?
If you have any other comments on how to make this plot look better, I'd definitely appreciate your comments and expertise.
Here is an image of my plot and the code to go with it.
import numpy as np
import pylab as pl
import matplotlib.pyplot as py
class Radar(object):
def __init__(self, fig, titles, labels, rect=None):
if rect is None:
rect = [0.05, 0.05, 0.95, 0.95]
self.n = len(titles)
self.angles = [a if a <=360. else a - 360. for a in np.arange(90, 90+360, 360.0/self.n)]
self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
for i in range(self.n)]
self.ax = self.axes[0]
self.ax.set_thetagrids(self.angles, labels=titles, fontsize=12, weight="bold", color="black")
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid("off")
ax.xaxis.set_visible(False)
self.ax.yaxis.grid(False)
for ax, angle, label in zip(self.axes, self.angles, labels):
ax.set_rgrids(range(1, 7), labels=label, angle=angle, fontsize=12)
ax.spines["polar"].set_visible(False)
ax.set_ylim(0, 6)
ax.xaxis.grid(True,color='black',linestyle='-')
pos=ax.get_rlabel_position()
ax.set_rlabel_position(pos+3)
def plot(self, values, *args, **kw):
angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
values = np.r_[values, values[0]]
self.ax.plot(angle, values, *args, **kw)
fig = pl.figure(figsize=(20, 20))
titles = [
"Canada", "Australia", "New\nZealand", "Japan", "China", "USA", "Mexico", "Finland", "Doha"
]
labels = [
list("abcde"), list("12345"), list("uvwxy"),
[" ", " ", "$156", "$158", "$160"],
list("jklmn"), list("asdfg"), list("qwert"), [" ", "4.3", "4.4", "4.5", "4.6"], list("abcde")
]
radar = Radar(fig, titles, labels)
radar.plot([1, 3, 2, 5, 4, 5, 3, 3, 2], "--", lw=1, color="b", alpha=.5, label="USA 2014")
radar.plot([2.3, 2, 3, 3, 2, 3, 2, 4, 2],"-", lw=1, color="r", alpha=.5, label="2014")
radar.plot([3, 4, 3, 4, 2, 2, 1, 3, 2], "-", lw=1, color="g", alpha=.5, label="2013")
radar.plot([4.5, 5, 4, 5, 3, 3, 4, 4, 2], "-", lw=1, color="y", alpha=.5, label="2012")
radar.ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.10),
fancybox=True, shadow=True, ncol=4)
py.title("Seattle, WA\nData from 2012 to 2014", weight="bold", fontsize=14)
fig = py.gcf()
fig.set_size_inches(6, 10, forward=True)
fig.savefig('test2png.png', dpi=100, bbox_inches="tight", pad_inches=1)

Unfortunately, you cannot have two different weights/font sizes within a single text object. But what you can do is add a new text object with a different weight.
I replaced the title call in your script with this:
py.text(0.5, 1.1, "Seattle, WA\n", weight="bold", fontsize=14,
transform=py.gca().transAxes, ha='center')
py.text(0.5, 1.1, "Data from 2012 to 2014",
transform=py.gca().transAxes, ha='center')
The result, I think, is something like what you were hoping for:

Related

Adding image generated from another library as inset in matplotlib

I've generated a network figure using vedo library and I'm trying to add this as an inset to a figure generated in matplotlib
import networkx as nx
import matplotlib.pyplot as plt
from vedo import *
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
G = nx.gnm_random_graph(n=10, m=15, seed=1)
nxpos = nx.spring_layout(G, dim=3, seed=1)
nxpts = [nxpos[pt] for pt in sorted(nxpos)]
nx_lines = [(nxpts[i], nxpts[j]) for i, j in G.edges()]
pts = Points(nxpts, r=12)
edg = Lines(nx_lines).lw(2)
# node values
values = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[30, 80, 10, 79, 70, 60, 75, 78, 65, 10],
[1, .30, .10, .79, .70, .60, .75, .78, .65, .90]]
time = [0.0, 0.1, 0.2] # in seconds
vplt = Plotter(N=1)
pts1 = pts.cmap('Blues', values[0])
vplt.show(
pts1, edg,
axes=False,
bg='white',
at=0,
interactive=False,
zoom=1.5
).screenshot("network.png")
ax = plt.subplot(111)
ax.plot(
[1, 2, 3], [1, 2, 3],
'go-',
label='line 1',
linewidth=2
)
arr_img = vplt.screenshot(returnNumpy=True, scale=1)
im = OffsetImage(arr_img, zoom=0.25)
ab = AnnotationBbox(im, (1, 0), xycoords='axes fraction', box_alignment=(1.1, -0.1), frameon=False)
ax.add_artist(ab)
plt.show()
ax.figure.savefig(
"output.svg",
transparent=True,
dpi=600,
bbox_inches="tight"
)
There resolution of the image in the inset is too low. Suggestions on how to add the inset without loss of resolution will be really helpful.
EDIT:
The answer posted below works for adding a 2D network, but I am still looking for ways that will be useful for adding a 3D network in the inset.
I am not familiar with vedo but the general procedure would be to create an inset_axis and plot the image with imshow. However, your code is using networkx which has matplotlib bindings and you can directly do this without vedo
EDIT: code edited for 3d plotting
import networkx as nx
import matplotlib.pyplot as plt
G = nx.gnm_random_graph(n=10, m=15, seed=1)
nxpos = nx.spring_layout(G, dim=3, seed=1)
nxpts = [nxpos[pt] for pt in sorted(nxpos)]
nx_lines = [(nxpts[i], nxpts[j]) for i, j in G.edges()]
# node values
values = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[30, 80, 10, 79, 70, 60, 75, 78, 65, 10],
[1, .30, .10, .79, .70, .60, .75, .78, .65, .90]]
time = [0.0, 0.1, 0.2] # in seconds
fig, ax = plt.subplots()
ax.plot(
[1, 2, 3], [1, 2, 3],
'go-',
label='line 1',
linewidth=2
)
from mpl_toolkits.mplot3d import (Axes3D)
from matplotlib.transforms import Bbox
rect = [.6, 0, .5, .5]
bbox = Bbox.from_bounds(*rect)
inax = fig.add_axes(bbox, projection = '3d')
# inax = add_inset_axes(,
# ax_target = ax,
# fig = fig, projection = '3d')
# inax.axis('off')
# set angle
angle = 25
inax.view_init(10, angle)
# hide axes, make transparent
# inax.set_facecolor('none')
# inax.grid('off')
import numpy as np
# plot 3d
seen = set()
for i, j in G.edges():
x = np.stack((nxpos[i], nxpos[j]))
inax.plot(*x.T, color = 'k')
if i not in seen:
inax.scatter(*x[0], color = 'skyblue')
seen.add(i)
if j not in seen:
inax.scatter(*x[1], color = "skyblue")
seen.add(j)
fig.show()

Adding one colorbar for hist2d subplots and make them adjacent

I am struggling with tweaking a plot, I have been working on.
I am facing to two problems:
The plots should be adjacent and with 0 wspace and hspace. I set both values to zero but still there are some spaces between the plots.
I would like to have one colorbar for all the subplots (they all the same range). Right now, the code adds a colorbar to the last subplot as i understand that it needs the third return value of hist2D.
Here is my code so far:
def plot_panel(pannel_plot):
fig, ax = plt.subplots(3, 2, figsize=(7, 7), gridspec_kw={'hspace': 0.0, 'wspace': 0.0}, sharex=True, sharey=True)
fig.subplots_adjust(wspace=0.0)
ax = ax.flatten()
xmin = 0
ymin = 0
xmax = 0.19
ymax = 0.19
hist2_num = 0
h =[]
for i, j in zip(pannel_plot['x'].values(), pannel_plot['y'].values()):
h = ax[hist2_num].hist2d(i, j, bins=50, norm=LogNorm(vmin=1, vmax=5000), range=[[xmin, xmax], [ymin, ymax]])
ax[hist2_num].set_aspect('equal', 'box')
ax[hist2_num].tick_params(axis='both', top=False, bottom=True, left=True, right=False,
labelsize=10, direction='in')
ax[hist2_num].set_xticks(np.arange(xmin, xmax, 0.07))
ax[hist2_num].set_yticks(np.arange(ymin, ymax, 0.07))
hist2_num += 1
fig.colorbar(h[3], orientation='vertical', fraction=.1)
plt.show()
And the corrsiponding result:
Result
I would be glad for any heads up that i am missing!
You can use ImageGrid, which was designed to make this kind of things easier
data = np.vstack([
np.random.multivariate_normal([10, 10], [[3, 2], [2, 3]], size=100000),
np.random.multivariate_normal([30, 20], [[2, 3], [1, 3]], size=1000)
])
from mpl_toolkits.axes_grid1 import ImageGrid
fig = plt.figure(figsize=(4, 6))
grid = ImageGrid(fig, 111, # similar to subplot(111)
nrows_ncols=(3, 2), # creates 2x2 grid of axes
axes_pad=0.1, # pad between axes in inch.
cbar_mode="single",
cbar_location="right",
cbar_pad=0.1
)
for ax in grid:
h = ax.hist2d(data[:, 0], data[:, 1], bins=100)
fig.colorbar(h[3], cax=grid.cbar_axes[0], orientation='vertical')
or
data = np.vstack([
np.random.multivariate_normal([10, 10], [[3, 2], [2, 3]], size=100000),
np.random.multivariate_normal([30, 20], [[2, 3], [1, 3]], size=1000)
])
from mpl_toolkits.axes_grid1 import ImageGrid
fig = plt.figure(figsize=(4, 6))
grid = ImageGrid(fig, 111, # similar to subplot(111)
nrows_ncols=(3, 2), # creates 2x2 grid of axes
axes_pad=0.1, # pad between axes in inch.
cbar_mode="single",
cbar_location="top",
cbar_pad=0.1
)
for ax in grid:
h = ax.hist2d(data[:, 0], data[:, 1], bins=100)
fig.colorbar(h[3], cax=grid.cbar_axes[0], orientation='horizontal')
grid.cbar_axes[0].xaxis.set_ticks_position('top')

Matplotlib: Polar radius label padding

Hi: Could you help me evenly space the radius labels around my polar plot? I want to be able to adjust the padding for each axis label individually.
I know how to adjust the padding for all the labels together, but I don't want to do that because it doesn't evenly space them from the plot (e.g. add padding to New Zealand and Finland but don't add padding to China or Canada).
I appreciate any help you can give me.
Here is an image for my plot and the code:
import numpy as np
import pylab as pl
import matplotlib.pyplot as py
class Radar(object):
def __init__(self, fig, titles, labels, rect=None):
if rect is None:
rect = [0.05, 0.05, 0.95, 0.95]
self.n = len(titles)
self.angles = [a if a <=360. else a - 360. for a in np.arange(90, 90+360, 360.0/self.n)]
self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
for i in range(self.n)]
self.ax = self.axes[0]
self.ax.set_thetagrids(self.angles, labels=titles,
fontsize=13, weight="normal", color="black")
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid("off")
ax.xaxis.set_visible(False)
self.ax.yaxis.grid(False)
for ax, angle, label in zip(self.axes, self.angles, labels):
ax.set_rgrids(range(1, 7), labels=label, angle=angle, fontsize=12)
ax.spines["polar"].set_visible(False)
ax.set_ylim(0, 6)
ax.xaxis.grid(True,color='black',linestyle='-')
pos=ax.get_rlabel_position()
ax.set_rlabel_position(pos+3)
def plot(self, values, *args, **kw):
angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
values = np.r_[values, values[0]]
self.ax.plot(angle, values, *args, **kw)
fig = pl.figure(figsize=(20, 20))
titles = [
"Canada", "Australia", "New\nZealand", "Japan",
"China", "USA", "Mexico", "Finland", "Doha"
]
labels = [
list("abcde"), list("12345"), list("uvwxy"),
[" ", " ", "$156", "$158", "$160"],
list("jklmn"), list("asdfg"), list("qwert"),
[" ", "4.3", "4.4", "4.5", "4.6"], list("abcde")
]
radar = Radar(fig, titles, labels)
radar.plot([1, 3, 2, 5, 4, 5, 3, 3, 2], "--", lw=1, color="b", alpha=.5, label="USA 2014")
radar.plot([2.3, 2, 3, 3, 2, 3, 2, 4, 2],"-", lw=1, color="r", alpha=.5, label="2014")
radar.plot([3, 4, 3, 4, 2, 2, 1, 3, 2], "-", lw=1, color="g", alpha=.5, label="2013")
radar.plot([4.5, 5, 4, 5, 3, 3, 4, 4, 2], "-", lw=1, color="y", alpha=.5, label="2012")
radar.ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.10),
fancybox=True, shadow=True, ncol=4)
py.text(0.5, 1.15, "Seattle, WA\n", weight="bold", fontsize=22,
transform=py.gca().transAxes, ha='center')
py.text(0.5, 1.15, "Market Data from 2012 to 2014", fontsize=14,
transform=py.gca().transAxes, ha='center')
fig = py.gcf()
fig.set_size_inches(6, 10, forward=True)
fig.savefig('test2png.png', dpi=100, bbox_inches="tight", pad_inches=1)

How to change axis color on polar chart

I'm not sure how my axes turned green, but I want them to be black.
Could you tell me what code to add to change my axes color to black and where to add the code?
I would like the axes to be solid black lines. Thanks for your help!
Here's the code I'm working with:
import numpy as np
import pylab as pl
import matplotlib.pyplot as py
class Radar(object):
def __init__(self, fig, titles, labels, rect=None):
if rect is None:
rect = [0.05, 0.05, 0.95, 0.95]
self.n = len(titles)
self.angles = [a if a <=360. else a - 360. for a in np.arange(90, 90+360, 360.0/self.n)]
self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
for i in range(self.n)]
self.ax = self.axes[0]
self.ax.set_thetagrids(self.angles, labels=titles, fontsize=12, weight="bold", color="black")
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid("off")
ax.xaxis.set_visible(False)
self.ax.yaxis.grid(False)
for ax, angle, label in zip(self.axes, self.angles, labels):
ax.set_rgrids(range(1, 7), labels=label, angle=angle, fontsize=12)
ax.spines["polar"].set_visible(False)
ax.set_ylim(0, 6)
def plot(self, values, *args, **kw):
angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
values = np.r_[values, values[0]]
self.ax.plot(angle, values, *args, **kw)
fig = pl.figure(figsize=(20, 20))
titles = [
"Canada", "Australia", "New Zealand", "Japan", "China", "USA", "Mexico", "Finland", "Doha"
]
labels = [
list("abcde"), list("12345"), list("uvwxy"),
[" ", " ", "$156", "$158", "$160"],
list("jklmn"), list("asdfg"), list("qwert"), [" ", "4.3", "4.4", "4.5", "4.6"], list("abcde")
]
radar = Radar(fig, titles, labels)
radar.plot([1, 3, 2, 5, 4, 5, 3, 3, 2], "--", lw=1, color="b", alpha=.5, label="USA 2014")
radar.plot([2.3, 2, 3, 3, 2, 3, 2, 4, 2],"-", lw=1, color="r", alpha=.5, label="2014")
radar.plot([3, 4, 3, 4, 2, 2, 1, 3, 2], "-", lw=1, color="g", alpha=.5, label="2013")
radar.plot([4.5, 5, 4, 5, 3, 3, 4, 4, 2], "-", lw=1, color="y", alpha=.5, label="2012")
radar.ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.10),
fancybox=True, shadow=True, ncol=4)
fig = py.gcf()
fig.set_size_inches(6, 10, forward=True)
fig.savefig('test2png.png', dpi=100, bbox_inches="tight", pad_inches=1)
You can set this with ax.xaxis.grid(). Just put the following line after you set_ylim(0, 6):
ax.xaxis.grid(True,color='k',linestyle='-')

How to remove polar gridlines and add major axis ticks

Could someone please help me remove the gridlines that form the rings inside my polar plot. I'd like to keep (and even bold) the axes and add ticks for each of the axis labels.
Here is the code that I'm working with, an image of the plot, and an image of what I want for the axes.
import numpy as np
import pylab as pl
import matplotlib.pyplot as py
class Radar(object):
def __init__(self, fig, titles, labels, rect=None):
if rect is None:
rect = [0.05, 0.05, 0.95, 0.95]
self.n = len(titles)
self.angles = [a if a <=360. else a - 360. for a in np.arange(90, 90+360, 360.0/self.n)]
self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
for i in range(self.n)]
self.ax = self.axes[0]
self.ax.set_thetagrids(self.angles, labels=titles, fontsize=12, weight="bold")
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid("off")
ax.xaxis.set_visible(False)
for ax, angle, label in zip(self.axes, self.angles, labels):
ax.set_rgrids(range(1, 7), labels=label, angle=angle, fontsize=12)
ax.spines["polar"].set_visible(False)
ax.set_ylim(0, 6)
def plot(self, values, *args, **kw):
angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
values = np.r_[values, values[0]]
self.ax.plot(angle, values, *args, **kw)
fig = pl.figure(figsize=(20, 20))
titles = [
"Canada", "Australia",
"New Zealand", "Japan", "China", "USA", "Mexico", "Finland", "Doha"
]
labels = [
list("abcde"), list("12345"), list("uvwxy"),
[" ", " ", "$156", "$158", "$160"],
list("jklmn"), list("asdfg"), list("qwert"), [" ", "4.3", "4.4", "4.5", "4.6"], list("abcde")
]
radar = Radar(fig, titles, labels)
radar.plot([1, 3, 2, 5, 4, 5, 3, 3, 2], "--", lw=1, color="b", alpha=.5, label="USA 2014")
radar.plot([2.3, 2, 3, 3, 2, 3, 2, 4, 2],"-", lw=1, color="r", alpha=.5, label="2014")
radar.plot([3, 4, 3, 4, 2, 2, 1, 3, 2], "-", lw=1, color="g", alpha=.5, label="2013")
radar.plot([4.5, 5, 4, 5, 3, 3, 4, 4, 2], "-", lw=1, color="y", alpha=.5, label="2012")
radar.ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.10),
fancybox=True, shadow=True, ncol=4)
fig = py.gcf()
fig.set_size_inches(6, 10, forward=True)
fig.savefig('test2png.png', dpi=100, bbox_inches="tight", pad_inches=1)
Desired look:
Current look:
You just need to set the yaxis.grid to False. For example, if you set:
self.ax.yaxis.grid(False)
in the line after you set self.ax.set_thetagrids(...), the circular gridlines are removed.

Resources