Formatting part of text in Matplotlib in Python - python

I would like to change the fontweight of part of some text I give to matplotlib's text command on a plot using matplotlib. For example, I would like the first word to be bold. Also, I would like to change the font weight and font to Times New Roman without affecting the rest of the labels, i.e. x-axis and y-axis labels.
Browsing the stack exchange, I came across the rc('text', usetex=True) command. When I use this, these changes affect the entire plot (i.e., the x-axis and y-axis labels as well). I would just like to format the text given to matplotlib's text command. Is there a way to do this?
Here's an example:
import numpy as np
import matplotlib.pyplot as plt
randomNumber = []
for index in range(0, 1000):
np.random.seed()
randomNumber.append(np.random.normal(0, 1, 1)[0])
plt.figure()
ax = plt.gca()
ax.hist(randomNumber, 12)
#plt.figure()
#plt.plot()
plt.rc('text', usetex=True)
ax.text(-2, 150, '\\textbf{test} testing', fontsize=16, fontname='Times New Roman')

Related

How to use a colored shape as yticks in matplotlib or seaborn?

I am working on a task called knowledge tracing which estimates the student mastery level over time. I would like to plot a similar figure as below using the Matplotlib or Seaborn.
It uses different colors to represent a knowledge concept, instead of a text. However, I have googled and found there is no article is talking about how we can do this.
I tried the following
# simulate a record of student mastery level
student_mastery = np.random.rand(5, 30)
df = pd.DataFrame(student_mastery)
# plot the heatmap using seaborn
marker = matplotlib.markers.MarkerStyle(marker='o', fillstyle='full')
sns_plot = sns.heatmap(df, cmap="RdYlGn", vmin=0.0, vmax=1.0)
y_limit = 5
y_labels = [marker for i in range(y_limit)]
plt.yticks(range(y_limit), y_labels)
Yet it simply returns the __repr__ of the marker, e.g., <matplotlib.markers.MarkerStyle at 0x1c5bb07860> on the yticks.
Thanks in advance!
While How can I make the xtick labels of a plot be simple drawings using matplotlib? gives you a general solution for arbitrary shapes, for the shapes shown here, it may make sense to use unicode symbols as text and colorize them according to your needs.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(42)
fig, ax = plt.subplots()
ax.imshow(np.random.rand(3,10), cmap="Greys")
symbolsx = ["⚪", "⚪", "⚫", "⚫", "⚪", "⚫","⚪", "⚫", "⚫","⚪"]
colorsx = np.random.choice(["#3ba1ab", "#b43232", "#8ecc3a", "#893bab"], 10)
ax.set_xticks(range(len(symbolsx)))
ax.set_xticklabels(symbolsx, size=40)
for tick, color in zip(ax.get_xticklabels(), colorsx):
tick.set_color(color)
symbolsy = ["◾", "◾", "◾"]
ax.set_yticks(range(len(symbolsy)))
ax.set_yticklabels(symbolsy, size=40)
for tick, color in zip(ax.get_yticklabels(), ["crimson", "gold", "indigo"]):
tick.set_color(color)
plt.show()

Matplotlib, usetex: Colorbar's font does not match plot's font

I have a matplotlib plot with a colorbar and can't seem to figure out how to match the fonts of the plot and the colorbar.
I try to use usetex for text handling, but it seems like only the ticks of the plot are affected, not the ticks of the colorbar.
Also, I have searched for solution quite a bit, so in the following code sample, there are a few different attempts included, but the result still is a bold font. Minimum failing code sample:
import matplotlib as mpl
import matplotlib.pyplot as plt
import sys
import colorsys
import numpy as np
mpl.rc('text', usetex=True)
plt.rcParams["font.family"] = "Times New Roman"
plt.rcParams["font.weight"] = 100
plt.rcParams["axes.labelweight"] = 100
plt.rcParams["figure.titleweight"] = 100
def draw():
colors = [colorsys.hsv_to_rgb(0.33, step /15, 1) for step in [2, 5, 8, 11, 14]]
mymap = mpl.colors.LinearSegmentedColormap.from_list('value',colors, N=5)
Z = [[0,0],[0,0]]
levels = range(2,15+4,3)
CS3 = plt.contourf(Z, levels, cmap=mymap)
plt.clf()
plt.figure(figsize=(20, 15))
plt.gca().set_aspect('equal')
cbar = plt.colorbar(CS3, ax=plt.gca(), shrink=0.5, fraction=0.5, aspect=30, pad=0.05, orientation="horizontal")
cbar.set_ticks([1.5 + x for x in [2,5,8,11,14]])
# attempts to make the fonts look the same
cbar.ax.set_xticklabels([1,2,3,4,5], weight="light", fontsize=16)
cbar.set_label("value", weight="ultralight", fontsize=32)
plt.setp(cbar.ax.xaxis.get_ticklabels(), weight='ultralight', fontsize=16)
for l in cbar.ax.xaxis.get_ticklabels():
l.set_weight("light")
plt.show()
draw()
Unfortunately, the fonts don't look the same at all. Picture:
I'm sure it's just a stupid misunderstanding of usetex on my part. Why does the usetex not seem to handle the colormap's font?
Thanks!
The issue here is that MPL wraps ticklabels in $ when usetex=True. This causes them to have different sizes than text that is not wrapped in $. When you force your ticks to be labeled with [1,2,3,4,5] these values are not wrapped in $, and are therefore rendered differently. I don't know the details of why this is, but I've run into the problem before myself.
I'd recommend wrapping your colorbar ticks in $, for example:
cbar.ax.set_xticklabels(['${}$'.format(tkval) for tkval in [1, 2, 3, 4, 5]])
From there you should be able to figure out how to adjust font sizes/weights so that they match and you get what you want.

How to increase plt.title font size?

I'm using Pythons matplotlib and this is my code:
plt.title('Temperature \n Humidity')
How can I just increase the font size of temperature instead of both the temperature & the humdity?
This does NOT work:
plt.title('Temperature \n Humidity', fontsize=100)
fontsize can be assigned inside dictionary fontdict which provides additional parameters fontweight, verticalalignment , horizontalalignment
The below snippet should work
plt.title('Temperature \n Humidity', fontdict = {'fontsize' : 100})
import matplotlib.pyplot as plt
plt.figtext(.5,.9,'Temperature', fontsize=100, ha='center')
plt.figtext(.5,.8,'Humidity',fontsize=30,ha='center')
plt.show()
Probably you want this. You can easily tweak the fontsize of both and adjust there placing by changing the first two figtext positional parameters.
ha is for horizontal alignment
Alternatively,
import matplotlib.pyplot as plt
fig = plt.figure() # Creates a new figure
fig.suptitle('Temperature', fontsize=50) # Add the text/suptitle to figure
ax = fig.add_subplot(111) # add a subplot to the new figure, 111 means "1x1 grid, first subplot"
fig.subplots_adjust(top=0.80) # adjust the placing of subplot, adjust top, bottom, left and right spacing
ax.set_title('Humidity',fontsize= 30) # title of plot
ax.set_xlabel('xlabel',fontsize = 20) #xlabel
ax.set_ylabel('ylabel', fontsize = 20)#ylabel
x = [0,1,2,5,6,7,4,4,7,8]
y = [2,4,6,4,6,7,5,4,5,7]
ax.plot(x,y,'-o') #plotting the data with marker '-o'
ax.axis([0, 10, 0, 10]) #specifying plot axes lengths
plt.show()
Output of alternative code:
PS: if this code give error like ImportError: libtk8.6.so: cannot open shared object file esp. in Arch like systems. In that case, install tk using sudo pacman -S tk or Follow this link
This has been mostly working for me across recent versions of Matplotlib (currently 2.0.2). It is helpful for generating presentation graphics:
def plt_resize_text(labelsize, titlesize):
ax = plt.subplot()
for ticklabel in (ax.get_xticklabels()):
ticklabel.set_fontsize(labelsize)
for ticklabel in (ax.get_yticklabels()):
ticklabel.set_fontsize(labelsize)
ax.xaxis.get_label().set_fontsize(labelsize)
ax.yaxis.get_label().set_fontsize(labelsize)
ax.title.set_fontsize(titlesize)
The odd for-loop construction seems to be necessary to adjust the size of each tic label.
Also, the above function should be called just before the call to plt.show(block=True), otherwise for whatever reason the title size occasionally remains unchanged.
Assuming you are using matplotlib to render some plots.
You might want to checkout Text rendering With LaTeX — Matplotlib
Here are some lines of code for your case
plt.rc('text', usetex=True)
plt.title(r"\begin{center} {\Large Temperature} \par {\large Humidity} \end{center}")
Hope that helps.
Simply do the following:
ax.set_title('This is the title',fontsize=20)
I don't want to go into this chart exactly
Universal method:
step one - make a distance between the main title and the chart:
from matplotlib import rcParams
rcParams['axes.titlepad'] = 20
then insert subtitle by setting coordinates:
ax.text(0.3, -0.56, 'subtitle',fontsize=12)

matplotlib: bold tick labels with scientific notation

I want to have bold tick labels with LaTeX-fonts in matplotlib. A sample plot can be found here:
sample plot
The code I am using:
import matplotlib as mpl
import matplotlib.pyplot as plt
f=plt.figure(figsize=(10,10))
ax = f.add_subplot(111)
x_data = [x for x in range(0, 200)]
y_data = [pow(x,6) for x in x_data]
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
plt.rc('font', size=24)
plt.rc('font', weight='bold')
plt.grid(True)
p3, = plt.plot(x_data,y_data,'g',linewidth = 7,ls='dashed',markersize=8,markeredgewidth=8)
ax.ticklabel_format(axis='y', style='sci', scilimits=(-2,2))
mpl.ticker.ScalarFormatter(useMathText = True)
plt.show()
The problem is, I would like to have the 1e13 in the upper corner to be displayed as $10^13$ as it would be if I leave out
mpl.ticker.ScalarFormatter(useMathText = True)
but then it is not in bold font. Is there any way to do this? I know that I could to all kind of tweaking with the original data by hand, but I would be totally happy to have an automatic solution.
And related to this question, I found the following thread:
matplotlib: format axis offset-values to whole numbers or specific number
There Joe Kington wrote a class FixedOrderFormatter(ScalarFormatter), which allows to change the power from 1e13 to 1e14, for example. Is there maybe even a way to combine the FixedOrderFormatter with the scientific notation to be $10^14$ with bold font instead of 1e14?

Matplotlib: disable powers of ten in log plot

Is there a simple way to make matplotlib not show the powers of ten in a log plot, and instead just show the numbers? I.e., instead of [10^1, 10^2, 10^3] display [10, 100, 1000]? I don't want to change the tickmark locations, just want to get rid of the powers of ten.
This is what I currently have:
I can change the labels themselves via xticks, however I then get mismatching fonts or sizes for the y tick labels. I am using TeX for this text. I've tried the following:
xx, locs = xticks()
ll = [r'\rm{%s}' % str(a) for a in xx]
xticks(xx, ll)
This gives the following result:
In this particular case, I could use the same LaTeX roman font, but the sizes and looks are different to those in the y axis. Plus, if I used a different LaTeX font in matplotlib this is going to be problematic.
Is there a more flexible way of switching off the power of ten notation?
Use a ScalarFormatter:
from matplotlib import rc
rc('text', usetex=True)
rc('font', size=20)
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot(111)
ax.semilogx(range(100))
ax.xaxis.set_major_formatter(ScalarFormatter())
plt.show()

Categories

Resources