No Plotting all values of X in xaxis and why there is the background grey? - matplotlib

I would like to get a plot with less data on xaxis. I have this very simple script. I put a 'range' for xaxis. Furthemore I would like that my background was white with contours black and not grey (see figure). How can I do?
import matplotlib.pyplot as plt
plt.figure()
# Increase the plot size and font size.
plt.rcParams["figure.figsize"] = (60,30)
plt.xticks(fontsize=40)
plt.yticks(fontsize=40)
plt.grid(True, color='gray', linestyle='dashed', linewidth=0.5, axis='y')
# Plot the learning curve.
plt.plot(df_stats['Training Loss'], color='b', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white', label="Training", linewidth=7)
plt.plot(df_stats['Valid. Loss'], color='g', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white',label="Validation", linewidth=7)
# Label the plot.
plt.title("Training & Validation Loss",fontsize=60)
plt.xlabel("Epoch", fontsize=52)
plt.ylabel("Loss", fontsize=52)
plt.legend(fontsize=50)
plt.xticks(list(range(1, 72)))
plt.show()

To set the X-axis ticks to a lower frequency, you will need to change the xticks to a lower frequency. One way to do this using numpy.arange().
Regarding the background color, the default is white. But, if for reason it is not, you can set it to white using the plot and axis facecolor() to white explicitly.
The code below is the updated version with these changes. Note that I used some dummy data to demonstrate the same.
Code
df_stats= pd.DataFrame(columns=['Training Loss', 'Valid. Loss'])
df_stats['Training Loss'] = list(range(1,72))
df_stats['Valid. Loss'] = df_stats['Training Loss'] * 2.1
import matplotlib.pyplot as plt
plt.figure()
# Background color of outer area
plt.figure(facecolor='white')
# Background color of the plot area
ax = plt.axes()
ax.set_facecolor("white")
# Increase the plot size and font size.
plt.rcParams["figure.figsize"] = (60,30)
plt.xticks(fontsize=40)
plt.yticks(fontsize=40)
plt.grid(True, color='gray', linestyle='dashed', linewidth=0.5, axis='y')
# Plot the learning curve.
plt.plot(df_stats['Training Loss'], color='b', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white', label="Training", linewidth=7)
plt.plot(df_stats['Valid. Loss'], color='g', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white',label="Validation", linewidth=7)
# Label the plot.
plt.title("Training & Validation Loss",fontsize=60)
plt.xlabel("Epoch", fontsize=52)
plt.ylabel("Loss", fontsize=52)
plt.legend(fontsize=50)
plt.xticks(list(np.arange(1, 72, 9)))
plt.show()
Output plot

Related

Add xticks within margins

I am trying create two plots that should have the same width when displayed in a row-wise fashion. I have noticed that adding xticks followed by tight_layout makes the plot (pcolormesh) decrease in width from increasing the x-margins. I would like to move the ticks in such a way that the x-margins are eliminated and both pcolormesh have the same width.
I have the following example:
import numpy as np, matplotlib.pyplot as plt
def plot(ticks=True):
fig, ax = plt.subplots(figsize=(6,1))
np.random.seed(42)
a = np.random.randn(1,6)
ax.pcolormesh(a)
plt.gca().invert_yaxis()
ax.xaxis.tick_top()
ax.set(yticklabels=[])
ax.tick_params(left=False, length=5)
if ticks:
ax.set_xticks([0, 3, 6])
else:
plt.axis('off')
plt.tight_layout()
plt.savefig(f'plot-{ticks}.png', dpi=300, bbox_inches='tight', pad_inches=0.0)
I get the following plots when running with and without the ticks:
The x-margins are not the same, which is more noticeable when increasing the font-size. How do I move the 3 label to right and the 6 label to the left to make both images have the same x-margins (0 margin)?
EDIT
Using the suggestion from Align specific x labels differently to each other? we have
import numpy as np, matplotlib.pyplot as plt
plt.rcParams.update({'font.size': 17})
fig, ax = plt.subplots(figsize=(6,1))
np.random.seed(42)
a = np.random.randn(1,6)
ax.pcolormesh(a)
plt.gca().invert_yaxis()
ax.xaxis.tick_top()
ax.set(yticklabels=[])
ax.tick_params(left=False, length=5)
# get list of x tick objects
xtick_objects = ax.xaxis.get_major_ticks()
xtick_objects[0].label1.set_horizontalalignment('left') # left align first tick
xtick_objects[-1].label1.set_horizontalalignment('right') # right align last tick
ax.set_xticks([0, 3, 6])
plt.tight_layout()
# plt.savefig(f'plot.png', dpi=300, bbox_inches='tight', pad_inches=0.0
plt.show()
which does not seem to change the alignment.

Matplotlib subplots size bigger than figure size

I discovered Matplotlib and I have a rendering problem. The 5 subplot I create step on each other, the xaxis labels and titles are behind the other plot.
Here is a part of the code I use :
fig, axs = plt.subplots(5,figsize=(8,25))
axs[0].plot(array_system_index, array_system_value, label="System", color="red", linewidth=1)
axs[0].set(xlabel="time", ylabel="Latency (µs)", yscale="log", title="System")
axs[0].axis([0, len(array_system_value), 1, 10000])
axs[1].plot(array_core0_index, array_core0_value, label="core 0", color="green", linewidth=1)
axs[1].set(xlabel="Time", ylabel="Latency (µs)", yscale="log", title="Core1")
axs[1].axis([0, len(array_core0_value), 1, 10000])
...
fig.tight_layout()
plt.show()
# fig.set_size_inches((15, 8), forward=False) # Break the png file
fig.savefig("my_graph.png", dpi=500)
Here is the result :
Graph
Do you know how can I increase the size of the figure itself ?
I tried to it after the subplot but it doesn't work and break the saved .png.

Matplotlib make color map have no transparency

def visualize(goal_x, goal_y, goal_z, epoch_arr):
# %% Create Color Map
colormap = plt.get_cmap("binary")
norm = matplotlib.colors.Normalize(vmin=min(epoch_arr), vmax=max(epoch_arr))
# %% 3D Plot
fig = plt.figure()
ax3D = fig.add_subplot(111, projection='3d')
ax3D.set_facecolor('xkcd:salmon')
ax3D.scatter(goal_x, goal_y, goal_z, s=100, c=colormap(norm(epoch_arr.values)), marker='o')
plt.show()
The above code produces the following picture:
However, as you can see there is a point in the right side that is clearly still not 100% opaque. You can see the grid lines through the point. How do I make the scatter plot points 100% opaque, no transparency?
Some tricks will help. Here I plot all the markers in white first, then plot again on top using the intended color.
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# make-up some data
goal_x = list(range(10))
goal_y = list(range(10))
goal_z = list(range(10))
epoch_arr = np.linspace(0,1,10)
fig = plt.figure(figsize=(8,8))
ax3D = fig.add_subplot(111, projection='3d')
ax3D.set_facecolor('xkcd:salmon')
# First plot: all markers are in white color
ax3D.scatter(goal_x, goal_y, goal_z, s=500, c='w', marker='o', alpha=1.0, zorder=10)
colormap = plt.get_cmap("binary")
norm = matplotlib.colors.Normalize(vmin=min(epoch_arr), vmax=max(epoch_arr))
#ax3D.scatter(goal_x, goal_y, goal_z, s=100, c=colormap(norm(epoch_arr.values)), marker='o')
# Second plot: use intended colormap
ax3D.scatter(goal_x, goal_y, goal_z, s=500, c='b', marker='o', zorder=11)
plt.show()
The resulting plot:
Setting alpha=1 should be enough.
ax3D.scatter(..., alpha=1)
Alternatively set depthshade=False
ax3D.scatter(..., depthshade=False)
The result will be the same in both cases.

matplotlib - Draw a heatmap/pixelmap with ability to edit individual pixel colours (different colormaps by row)

I'm trying to draw a heat map/pixelmap representation of a matrix using matplotlib. I currently have the following code which gives me the pixelmap as required (adapted from Heatmap in matplotlib with pcolor?):
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('0123')
data = np.array([[0,1,2,0],
[1,0,1,1],
[1,2,0,0],
[0,0,0,1]])
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
ax.yaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
ax.xaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
# Set the location of the minor ticks to the edge of pixels for the x grid
minor_locator = AutoMinorLocator(2)
ax.xaxis.set_minor_locator(minor_locator)
# Lets turn off the actual minor tick marks though
for tickmark in ax.xaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
# Set the location of the minor ticks to the edge of pixels for the y grid
minor_locator = AutoMinorLocator(2)
ax.yaxis.set_minor_locator(minor_locator)
# Lets turn off the actual minor tick marks though
for tickmark in ax.yaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
plt.show()
Which gives the following plot:
However I would like to extend this such that on mouse click I can highlight a 'row' in the pixelmap in green, e.g. if the user selected row 'C' I would have (I appreciate the green highlight is not clear for pixels with a 0 value):
I know how to deal with the mouse events but I'm not sure how to modify the colour of a single row in the pixelmap. It would also help if I could set labels for individual pixels of the pixel map to be retrieved on mouse click, as opposed to using the mouse x/y location to index the label lists.
I have figured out my own problem, with help from this question:
Plotting of 2D data : heatmap with different colormaps.
The code is below and the comments should explain the steps taken clearly.
import matplotlib.pyplot as plt
import numpy as np
from numpy.ma import masked_array
import matplotlib.cm as cm
from matplotlib.ticker import AutoMinorLocator
column_labels = list('ABCD')
row_labels = list('0123')
data = np.array([[0,1,2,0],
[1,0,1,1],
[1,2,0,0],
[0,0,0,1]])
fig, ax = plt.subplots()
# List to keep track of handles for each pixel row
pixelrows = []
# Lets create a normalizer for the whole data array
norm = plt.Normalize(vmin = np.min(data), vmax = np.max(data))
# Let's loop through and plot each pixel row
for i, row in enumerate(data):
# First create a mask to ignore all others rows than the current
zerosarray = np.ones_like(data)
zerosarray[i, :] = 0
plotarray = masked_array(data, mask=zerosarray)
# If we are not on the 3rd row down let's use the red colormap
if i != 2:
pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Reds))
# Otherwise if we are at the 3rd row use the green colormap
else:
pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Greens))
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0]), minor=False)
ax.set_yticks(np.arange(data.shape[1]), minor=False)
# want a more natural, table-like display
ax.xaxis.tick_top()
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
ax.yaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
ax.xaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
# Set the location of the minor ticks to the edge of pixels for the x grid
minor_locator = AutoMinorLocator(2)
ax.xaxis.set_minor_locator(minor_locator)
# Lets turn of the actual minor tick marks though
for tickmark in ax.xaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
# Set the location of the minor ticks to the edge of pixels for the y grid
minor_locator = AutoMinorLocator(2)
ax.yaxis.set_minor_locator(minor_locator)
# Lets turn of the actual minor tick marks though
for tickmark in ax.yaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
plt.show()

Matplotlib: coloring axis/tick labels

How would one color y-axis label and tick labels in red?
So for example the "y-label" and values 0 through 40, to be colored in red.
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(10)
fig = plt.figure()
ax = plt.subplot(111)
ax.set_ylabel("y-label")
for i in xrange(5):
ax.plot(x, i * x, label='$y = %ix$' % i)
ax.legend()
plt.show()
label = plt.ylabel("y-label")
label.set_color("red")
similarly, you can obtain and modify the tick labels:
[i.set_color("red") for i in plt.gca().get_xticklabels()]
The xlabel can be colorized when setting it,
ax.set_xlabel("x-label", color="red")
For setting the ticklabels' color, one may either use tick_params, which sets the ticklabels' as well as the ticks' color
ax.tick_params(axis='x', colors='red')
Alternatively, plt.setp can be used to only set the ticklabels' color, without changing the ticks' color.
plt.setp(ax.get_xticklabels(), color="red")
Note that for changing the properties on the y-axis, one can replace the x with a y in the above.