Common Pitfalls Encountered When Using Python Libraries
1. Color Parameter c in matplotlib's scatter Plot Function
In matplotlib, you can specify colors for scatter plots by setting the c parameter of the scatter function.
Setting Scatter Plot Colors:
- Single Color: Set the
cparameter to a color name string, such as'red'or'blue'.
import matplotlib.pyplot as plt
x = 1
y = 1
plt.scatter(x, y, c='red')
plt.show()
- RGB Colors: Set the
cparamter to a 3-element RGB tuple, where each value ranges from 0 to 1.
import matplotlib.pyplot as plt
x = 1
y = 1
plt.scatter(x, y, c=(0.5, 0.2, 0.8))
plt.show()
- Custom Colormaps: Set the
cparameter to a vector with the same length as the number of data points, then use a colormap function to define the color mappping.
A colormap is a series of colors that transition from a starting color to an ending color. In data visualization, colormaps are used to highlight patterns in data. The pyplot module includes several built-in colormaps.
import matplotlib.pyplot as plt
x_vals = list(range(1, 1001)) # numbers 1 through 1000
y_vals = [x**2 for x in x_vals] # compute squared values
plt.scatter(x_vals, y_vals, c=y_vals, cmap=plt.cm.Blues, s=40)
# Colormap - color gradient: smaller y values appear light blue,
# larger y values appear dark blue.
plt.show()
The examples above demonstrate how to use single colors, RGB tuples, and custom colormaps to color scatter plots. Choose the appropriate method based on your specific needs.
2. matplotlib Hiding Axes Fails to Work
During practice creating a random walk visualization with matplotlib's scatter function, the following code was used to hide the coordinate axes:
# Hide axes
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
After execution, the axes remained visible, and in PyCharm the random walk chart didn't even render.
Two issues were identified:
-
The axis hiding configuration must be set before the scatter call, otherwise it has no effect. The code to hide axes needs to be placed before
plt.scatter(). -
When using
plt.axes(), you must assign it to a variable and then call methods on that variable for it to work properly.
current_axes = plt.axes()
current_axes.get_xaxis().set_visible(False)
current_axes.get_yaxis().set_visible(False)
After applying these fixes, the axes were successfully hidden.
Example:
point_numbers = list(range(rw.num_points))
# Hide axes: use plt.axes() to modify axis visibility
current_axes = plt.axes()
current_axes.get_xaxis().set_visible(False)
current_axes.get_yaxis().set_visible(False)
# Color points based on their order in the walk
plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues, s=5)
# Highlight start and end points
plt.scatter(0, 0, c='green', edgecolors='none', s=100)
plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none', s=100)
3. Pygal Chart Font Size Settings Not Taking Effect
Problematic Code:
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18
This code sets the font sizes for the chart title, secondary labels, and major labels. Secondary labels include the x-axis item names and most y-axis numbers. Major labels are the y-axis ticks at multiples of 5000, which should be larger to distinguish them from secondary labels.
Corrected Code:
my_style = LS('#333366', base_style=LCS)
my_style.title_font_size = 24
my_style.label_font_size = 14
my_style.major_label_font_size = 16
# Initialize config for chart styling
my_config = pygal.Config()
...
chart = pygal.Bar(my_config, style=my_style)
The code below is based on the "Most-Starred Python Projects on GitHub" example from Chapter 17.2.1 of Python Crash Course:
import requests
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS
# Make API call and store response
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
response = requests.get(url)
print("Status code:", response.status_code)
# Store API response in a variable
data = response.json()
print("Total repositories:", data['total_count'])
# Extract repository information
repo_list = data['items']
names, stars = [], []
for repo in repo_list:
names.append(repo['name'])
stars.append(repo['stargazers_count'])
# Visualization
my_style = LS('#333366', base_style=LCS)
my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_legend = False
# Font size settings below are incorrect
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18
my_config.truncate_label = 15
my_config.show_y_guides = False
my_config.width = 1000
chart = pygal.Bar(my_config, style=my_style)
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names
chart.add('', stars)
chart.render_to_file('python_repos.svg')
After consulting the Pygal documentation, it became clear why the font size settings weren't working.
Looking at the pygal.config.Config class documentation revealed that title_font_size, label_font_size, and major_label_font_size are not attributes of the Config class.
Further investigation of the pygal.style.Style class showed that these three font size attributes are defined there. Additionally, the Config class contains a style attribute that references a Style class instance.
class Style(object):
"""Styling class containing colors for the CSS generation"""
plot_background = 'rgba(255, 255, 255, 1)'
background = 'rgba(249, 249, 249, 1)'
value_background = 'rgba(229, 229, 229, 1)'
foreground = 'rgba(0, 0, 0, .87)'
foreground_strong = 'rgba(0, 0, 0, 1)'
foreground_subtle = 'rgba(0, 0, 0, .54)'
font_family = ('Consolas, "Liberation Mono", Menlo, Courier, monospace')
label_font_family = None
major_label_font_family = None
value_font_family = None
value_label_font_family = None
tooltip_font_family = None
title_font_family = None
legend_font_family = None
no_data_font_family = None
label_font_size = 10
major_label_font_size = 10
value_font_size = 16
value_label_font_size = 10
tooltip_font_size = 14
title_font_size = 16
legend_font_size = 14
no_data_font_size = 64
When my_config.title_font_size = 24 was commented out, the rendered chart appeared unchanged, confirming the setting had no effect.
When my_config.style.title_font_size = 24 was tried instead, the chart title font size still didn't change. Debugging revealed that title_font_size defaults to a value of 16.
The solution: After creating the Bar instance, modifying the style through the chart object works:
chart = pygal.Bar(my_config, style=my_style)
chart.config.style.title_font_size = 24
This successfully changed the title font size.
To understand why my_config.style.title_font_size = 24 didn't work, one must trace the parameter passing during Bar instantiation. Debugging revealed that when creating a Bar instance, the BaseGraph class initialization runs first:
class BaseGraph(object):
_adapters = []
def __init__(self, config=None, **kwargs):
if config:
if isinstance(config, type):
config = config()
else:
config = config.copy()
else:
config = Config()
config(**kwargs)
self.config = config
my_config is passed to BaseGraph's config, including its style attribute, where title_font_size is 24 at that point. However, the problem occurs with the **kwargs processing. After **kwargs is applied, title_font_size reverts to its default value of 16.
The **kwargs only captures the style keyword argument from my_style. Since my_style is a Style class instance created with only positional arguments (color and base_style), its title_font_size remains at the default value of 16. When passed as a keyword arguement to the Bar instance, it overwrites the earlier setting.
Understanding this parameter passing flow reveals the correct approaches to modifying font sizes:
Method 1: Modify through the chart object after instantiation:
chart = pygal.Bar(my_config, style=my_style)
chart.config.style.title_font_size = 24
Method 2: Modify the my_style object directly:
my_style.title_font_size = 24
Method 3: Pass the font size when creating the style instance:
my_style = LS('#333366', base_style=LCS, title_font_size=24)
Method 4: Modify the style attribute within the config object and reuse it:
my_config.style.title_font_size = 24
my_config.style = LS('#333366', base_style=LCS)
chart = pygal.Bar(my_config)
Root Cause: This issue arose from breaking changes introduced in Pygal 2.0.0, where font size attributes were moved from the Config class to the Style class.