"ValueError: Invalid RGBA argument: None" when plotting via matplotlib ax.bar() for creating a windrose using custom colormaps
"ValueError: Invalid RGBA argument: None" when plotting via matplotlib ax.bar() for creating a windrose using custom colormaps
我们的目标是创建一个如下图所示的风向玫瑰:
错误本身发生在通过 fig.savefig()
保存绘图时,但到目前为止我意识到错误在于所使用的颜色映射(例如考虑到 )。
尝试将条形图添加到 WindroseAxes()
- 轴 - 实例,该实例以前工作得很好。
这可以通过 from windrose import WindroseAxes
实现。
我在这里提到它是否在问题中起作用。
# * Instantiate windrose-axis related to the global figure and the just created rectangle
# NOTE on passing theta-labels: need to be passed, otherwise an error will be thrown like 'keyword "theta_labels" does not exist'
# --> from windrose.py: self.theta_labels = kwargs.pop("theta_labels") or ["E", "N-E", "N", "N-W", "W", "S-W", "S", "S-E"]
ax = WindroseAxes(fig, rect, theta_labels=theta_labels)
fig.add_axes(ax)
使用的数据框的细节:
sub_df.info()
None
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 7130 entries, 2018-07-01 00:05:00+02:00 to 2018-07-31 23:55:00+02:00
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Atm. pressure mean 7130 non-null float64
1 Daily cumulative precipitation 7130 non-null float64
2 Precipitation 7130 non-null float64
3 RH_mean 7130 non-null float64
4 T_mean 7130 non-null float64
5 Wind direction mean 7130 non-null float64
6 Wind speed max 7130 non-null float64
7 Wind speed mean 7130 non-null float64
dtypes: float64(8)
memory usage: 821.3 KB
在接下来的内容中,我将描述 ax.bar()
- 函数(意图绘制风玫瑰) 和相关的颜色条 是如何绘制的:
# * Define colormap
# Colormap increases the contrast from 0 to 1 in blue (or the color of choice)
# NOTE on type: <matplotlib.colors.LinearSegmentedColormap object at 0x7fd8b7d3d850>
cmap = plt.cm.Blues # pylint: disable=no-member
## * Get bins for colormap used for all subplots equally * ##
# i) Get maximum value
# Use .max() instead of max(), otherwise NaN could be considered the maximum
real_max_val = df[var_name].max()
# Maximum value here: 11 (m/s)
max_val = real_max_val.round()
# NOTE on scope: when rounded down, add 1 to make it greater than the actual maximum value
if max_val < real_max_val:
max_val += 1
# ii) Set the bins linearly (not logarithmically as often seen)
# NOTE: units are assumed in meters per second (m/s)
# NOTE on bins: divides each wind-bar into e.g. 6 bins == stepnumber in linspace (default)
# NOTE on minimum value: the lowest possible is 0 m/s
bins_bar_plot = np.linspace(0, max_val, num_of_bins) # (start, end, stepnumber)
cmap_norm = mpl.colors.Normalize(vmin=0, vmax=max_val)
# * Create plot based on the current sub-df
ax.bar(sub_df['Wind direction mean'],
sub_df['Wind speed mean'],
normed=True,
facecolor=(0.03137254901960784, 0.18823529411764706, 0.4196078431372549, 1.0),
bins=array([ 0. , 2.2, 4.4, 6.6, 8.8, 11. ]),
cmap=cmap,
alpha=1.0,
opening=1.0,
"grey"="grey",
linewidth=0.1)
涉及到的colorbar是这样实现的:
fig.subplots_adjust(right=0.8)
# [x_coord start, y_coord start, total width, total height] - all in percent of the figure dimensions
cbar_ax = fig.add_axes([0.95, 0.15, 0.025, 0.7])
cbar = mpl.colorbar.ColorbarBase(cbar_ax,
cmap=cmap,
norm=cmap_norm,
spacing='proportional',
alpha=1.0)
cbar.set_label("{} {}".format('Wind speed mean', tools.units("Wind speed")),
color=None,
weight=None,
fontsize=None)
# NOTE: vertically oriented colorbar: y-label
# Length of ticklabels here: 6
new_yticklabels = np.linspace(0, max_val,
len(list(cbar.ax.get_yticklabels())))
new_yticklabels = np.around(new_yticklabels, decimals=1)
# New ticklabels here: array([ 0. , 2.2, 4.4, 6.6, 8.8, 11. ])
cbar.ax.set_yticklabels(new_yticklabels,
color=None,
weight=None,
fontsize=None)
控制台打印的整个错误回溯是:
ValueError Traceback (most recent call last)
~/Desktop/Programming/Python/Scripts/General/Plotting/windrose_plotting.py in <module>
184 textcolor="blue")
185 # * Carry out plot of the current sub-df
--> 186 plot.windrose_subplot(
187 df=df_plot.loc[m_loc],
188 desired_years=desired_years,
~/Dokumente/Allgemeines_material/Sonstiges/Programming/Python/Scripts/General/Plotting/plotting.py in windrose_subplot(df, figsize, groupby_freq, desired_years, desired_months, theta_labels, max_cols_per_row, ax_title_pos, cmap, y_coord_suptitle_dict, title_font_size, savepath, plot_file_extensions, normed, opening_bar_plot, num_of_bins, edgecolor, edge_linewidth, meteo_loc, add_info, transparent, alpha, label_color, font_weight, special_textfont_size, save_plotting_data_to_plain_text_AS_WELL, save_plotting_data_to_plain_text_ONLY)
6957
6958 # * Finally, either show or save the current plot
-> 6959 aux_plot.show_or_save_plot(path=savepath,
6960 basename=titlestr,
6961 transparent=transparent,
~/Dokumente/Allgemeines_material/Sonstiges/Programming/Python/Scripts/General/Plotting/auxiliary_plotting_functions.py in show_or_save_plot(fig, path, basename, file_extensions, dpi, legend, bbox_inches, transparent, legend_is_inside, remove_surrounding_whitespace, use_plotly, plotly_show_renderer, plotly_default_template, plotly_axlabel_size, plotly_title_label_size, plotly_font_family, plotly_font_color, linux_dir_sep, save_plotting_data_to_plain_text_AS_WELL, save_plotting_data_to_plain_text_ONLY)
3549
3550 # Carry out the saving procedure building up on the save-fig function
-> 3551 save_figs(path,
3552 fig=fig,
3553 file_extensions=file_extensions,
~/Dokumente/Allgemeines_material/Sonstiges/Programming/Python/Scripts/General/Plotting/auxiliary_plotting_functions.py in save_figs(filename, fig, file_extensions, dpi, standard_dpi, legend, bbox_inches, transparent, remove_surrounding_whitespace, legend_is_inside, linux_dir_sep, use_plotly, plotly_default_template, plotly_axlabel_size, plotly_title_label_size, plotly_font_family, plotly_font_color, save_plotting_data_to_plain_text_AS_WELL, save_plotting_data_to_plain_text_ONLY)
2395 if not remove_surrounding_whitespace:
2396 # Call savefig-method pertaining to a pyplot-fig-object with its provided kwargs
-> 2397 fig.savefig(filename + t,
2398 dpi=dpi,
2399 bbox_inches=bbox_inches,
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/figure.py in savefig(self, fname, transparent, **kwargs)
2309 patch.set_edgecolor('none')
2310
-> 2311 self.canvas.print_figure(fname, **kwargs)
2312
2313 if transparent:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2191 else suppress())
2192 with ctx:
-> 2193 self.figure.draw(renderer)
2194
2195 bbox_inches = self.figure.get_tightbbox(
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/figure.py in draw(self, renderer)
1861
1862 self.patch.draw(renderer)
-> 1863 mimage._draw_list_compositing_images(
1864 renderer, self, artists, self.suppressComposite)
1865
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/projections/polar.py in draw(self, renderer, *args, **kwargs)
993 self.yaxis.set_clip_path(self.patch)
994
--> 995 Axes.draw(self, renderer, *args, **kwargs)
996
997 def _gen_axes_patch(self):
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/axes/_base.py in draw(self, renderer, inframe)
2746 renderer.stop_rasterizing()
2747
-> 2748 mimage._draw_list_compositing_images(renderer, self, artists)
2749
2750 renderer.close_group('axes')
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/axis.py in draw(self, renderer, *args, **kwargs)
1167
1168 for tick in ticks_to_draw:
-> 1169 tick.draw(renderer)
1170
1171 # scale up the axis label box to also find the neighbors, not
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/axis.py in draw(self, renderer)
289 for artist in [self.gridline, self.tick1line, self.tick2line,
290 self.label1, self.label2]:
--> 291 artist.draw(renderer)
292 renderer.close_group(self.__name__)
293 self.stale = False
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/text.py in draw(self, renderer)
695
696 gc = renderer.new_gc()
--> 697 gc.set_foreground(textobj.get_color())
698 gc.set_alpha(textobj.get_alpha())
699 gc.set_url(textobj._url)
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/backend_bases.py in set_foreground(self, fg, isRGBA)
953 self._rgb = fg
954 else:
--> 955 self._rgb = colors.to_rgba(fg)
956
957 def set_joinstyle(self, js):
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
187 rgba = None
188 if rgba is None: # Suppress exception chaining of cache lookup failure.
--> 189 rgba = _to_rgba_no_colorcycle(c, alpha)
190 try:
191 _colors_full_map.cache[c, alpha] = rgba
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/colors.py in _to_rgba_no_colorcycle(c, alpha)
261 # tuple color.
262 if not np.iterable(c):
--> 263 raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
264 if len(c) not in [3, 4]:
265 raise ValueError("RGBA sequence should have length 3 or 4")
ValueError: Invalid RGBA argument: None
正如@JohanC 指出的那样,将 None
传递给 set_yticklabels
的 color
-kwarg 导致了 违反直觉的错误消息 我的问题。
避免 None
成功了,现在有效了。
为了安全起见,我编写了一个函数,避免将 None
传递给所涉及的任何 key-value 个参数(“kwargs”),可以在下面找到。
这是为了自动化一切,避免在每个需要彩色标签的绘图函数中编码过多。
该功能包括标记坐标轴、标题和颜色条的情况。
def set_ticklabels_or_title_of_current_ax(ax_or_cbar=None,
labels=None,
label_type=None,
ax_title_pos=(0.5, 0.985),
label_color=None,
font_weight=None,
special_textfont_size=None):
"""Function docs:\n
Avoid too much code in the main plotting function.
# NOTE on scope: not all of them are accepted as None since they could override the initial value
# Docs: https://whosebug.com/questions/63245556/valueerror-invalid-rgba-argument-none-when-plotting-via-matplotlib-ax-bar?noredirect=1#comment111839077_63245556
"""
# Check tick type passed
if label_type is None:
raise Exception("The user must pass a tick type (x or y).")
# Check whether an axis has been passed by the user
if ax_or_cbar is None and label_type.lower() in [
"x", "x-axis", "y", "y-axis", "title"
]:
ax_or_cbar = plt.gca()
# In the case that all variables were passed as None, return the axis unchanged
# NOTE: the function used here "check_if_any_or_all_of_the_passed_vars_are_None()" is a custom function, not included here: can be ignored
if tools.check_if_any_or_all_of_the_passed_vars_are_None(
[label_color, font_weight, special_textfont_size],
raise_error_within_function=False,
any_is_None=False):
# Return the ax unchanged
return ax_or_cbar
# * Check if labels were passed * #
if labels is None:
if label_type.lower() in ["x", "x-axis"]:
labels = [elem.get_text() for elem in list(ax_or_cbar.get_xticklabels())]
elif label_type.lower() in ["y", "y-axis"]:
labels = [elem.get_text() for elem in list(ax_or_cbar.get_yticklabels())]
elif label_type.lower() in ["title", "cbar title"]:
raise Exception("No title label has been passed.")
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
labels = list(ax_or_cbar.ax.get_yticklabels())
# * Check which variables were passed as None * #
if label_color is not None and font_weight is not None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_color is not None and font_weight is not None and special_textfont_size is None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
color=label_color,
weight=font_weight)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
color=label_color,
weight=font_weight)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color,
weight=font_weight)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, color=label_color, weight=font_weight)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
color=label_color,
weight=font_weight)
elif label_color is not None and font_weight is None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_color is None and font_weight is not None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_color is None and font_weight is None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels, fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels, fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
fontsize=special_textfont_size)
elif label_color is None and font_weight is not None and special_textfont_size is None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels, weight=font_weight)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels, weight=font_weight)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
weight=font_weight)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, weight=font_weight)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels, weight=font_weight)
elif label_color is not None and font_weight is None and special_textfont_size is None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels, color=label_color)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels, color=label_color)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, color=label_color)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels, color=label_color)
# Return updated axis to user
return ax_or_cbar
我们的目标是创建一个如下图所示的风向玫瑰:
错误本身发生在通过 fig.savefig()
保存绘图时,但到目前为止我意识到错误在于所使用的颜色映射(例如考虑到
尝试将条形图添加到 WindroseAxes()
- 轴 - 实例,该实例以前工作得很好。
这可以通过 from windrose import WindroseAxes
实现。
我在这里提到它是否在问题中起作用。
# * Instantiate windrose-axis related to the global figure and the just created rectangle
# NOTE on passing theta-labels: need to be passed, otherwise an error will be thrown like 'keyword "theta_labels" does not exist'
# --> from windrose.py: self.theta_labels = kwargs.pop("theta_labels") or ["E", "N-E", "N", "N-W", "W", "S-W", "S", "S-E"]
ax = WindroseAxes(fig, rect, theta_labels=theta_labels)
fig.add_axes(ax)
使用的数据框的细节:
sub_df.info()
None
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 7130 entries, 2018-07-01 00:05:00+02:00 to 2018-07-31 23:55:00+02:00
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Atm. pressure mean 7130 non-null float64
1 Daily cumulative precipitation 7130 non-null float64
2 Precipitation 7130 non-null float64
3 RH_mean 7130 non-null float64
4 T_mean 7130 non-null float64
5 Wind direction mean 7130 non-null float64
6 Wind speed max 7130 non-null float64
7 Wind speed mean 7130 non-null float64
dtypes: float64(8)
memory usage: 821.3 KB
在接下来的内容中,我将描述 ax.bar()
- 函数(意图绘制风玫瑰) 和相关的颜色条 是如何绘制的:
# * Define colormap
# Colormap increases the contrast from 0 to 1 in blue (or the color of choice)
# NOTE on type: <matplotlib.colors.LinearSegmentedColormap object at 0x7fd8b7d3d850>
cmap = plt.cm.Blues # pylint: disable=no-member
## * Get bins for colormap used for all subplots equally * ##
# i) Get maximum value
# Use .max() instead of max(), otherwise NaN could be considered the maximum
real_max_val = df[var_name].max()
# Maximum value here: 11 (m/s)
max_val = real_max_val.round()
# NOTE on scope: when rounded down, add 1 to make it greater than the actual maximum value
if max_val < real_max_val:
max_val += 1
# ii) Set the bins linearly (not logarithmically as often seen)
# NOTE: units are assumed in meters per second (m/s)
# NOTE on bins: divides each wind-bar into e.g. 6 bins == stepnumber in linspace (default)
# NOTE on minimum value: the lowest possible is 0 m/s
bins_bar_plot = np.linspace(0, max_val, num_of_bins) # (start, end, stepnumber)
cmap_norm = mpl.colors.Normalize(vmin=0, vmax=max_val)
# * Create plot based on the current sub-df
ax.bar(sub_df['Wind direction mean'],
sub_df['Wind speed mean'],
normed=True,
facecolor=(0.03137254901960784, 0.18823529411764706, 0.4196078431372549, 1.0),
bins=array([ 0. , 2.2, 4.4, 6.6, 8.8, 11. ]),
cmap=cmap,
alpha=1.0,
opening=1.0,
"grey"="grey",
linewidth=0.1)
涉及到的colorbar是这样实现的:
fig.subplots_adjust(right=0.8)
# [x_coord start, y_coord start, total width, total height] - all in percent of the figure dimensions
cbar_ax = fig.add_axes([0.95, 0.15, 0.025, 0.7])
cbar = mpl.colorbar.ColorbarBase(cbar_ax,
cmap=cmap,
norm=cmap_norm,
spacing='proportional',
alpha=1.0)
cbar.set_label("{} {}".format('Wind speed mean', tools.units("Wind speed")),
color=None,
weight=None,
fontsize=None)
# NOTE: vertically oriented colorbar: y-label
# Length of ticklabels here: 6
new_yticklabels = np.linspace(0, max_val,
len(list(cbar.ax.get_yticklabels())))
new_yticklabels = np.around(new_yticklabels, decimals=1)
# New ticklabels here: array([ 0. , 2.2, 4.4, 6.6, 8.8, 11. ])
cbar.ax.set_yticklabels(new_yticklabels,
color=None,
weight=None,
fontsize=None)
控制台打印的整个错误回溯是:
ValueError Traceback (most recent call last)
~/Desktop/Programming/Python/Scripts/General/Plotting/windrose_plotting.py in <module>
184 textcolor="blue")
185 # * Carry out plot of the current sub-df
--> 186 plot.windrose_subplot(
187 df=df_plot.loc[m_loc],
188 desired_years=desired_years,
~/Dokumente/Allgemeines_material/Sonstiges/Programming/Python/Scripts/General/Plotting/plotting.py in windrose_subplot(df, figsize, groupby_freq, desired_years, desired_months, theta_labels, max_cols_per_row, ax_title_pos, cmap, y_coord_suptitle_dict, title_font_size, savepath, plot_file_extensions, normed, opening_bar_plot, num_of_bins, edgecolor, edge_linewidth, meteo_loc, add_info, transparent, alpha, label_color, font_weight, special_textfont_size, save_plotting_data_to_plain_text_AS_WELL, save_plotting_data_to_plain_text_ONLY)
6957
6958 # * Finally, either show or save the current plot
-> 6959 aux_plot.show_or_save_plot(path=savepath,
6960 basename=titlestr,
6961 transparent=transparent,
~/Dokumente/Allgemeines_material/Sonstiges/Programming/Python/Scripts/General/Plotting/auxiliary_plotting_functions.py in show_or_save_plot(fig, path, basename, file_extensions, dpi, legend, bbox_inches, transparent, legend_is_inside, remove_surrounding_whitespace, use_plotly, plotly_show_renderer, plotly_default_template, plotly_axlabel_size, plotly_title_label_size, plotly_font_family, plotly_font_color, linux_dir_sep, save_plotting_data_to_plain_text_AS_WELL, save_plotting_data_to_plain_text_ONLY)
3549
3550 # Carry out the saving procedure building up on the save-fig function
-> 3551 save_figs(path,
3552 fig=fig,
3553 file_extensions=file_extensions,
~/Dokumente/Allgemeines_material/Sonstiges/Programming/Python/Scripts/General/Plotting/auxiliary_plotting_functions.py in save_figs(filename, fig, file_extensions, dpi, standard_dpi, legend, bbox_inches, transparent, remove_surrounding_whitespace, legend_is_inside, linux_dir_sep, use_plotly, plotly_default_template, plotly_axlabel_size, plotly_title_label_size, plotly_font_family, plotly_font_color, save_plotting_data_to_plain_text_AS_WELL, save_plotting_data_to_plain_text_ONLY)
2395 if not remove_surrounding_whitespace:
2396 # Call savefig-method pertaining to a pyplot-fig-object with its provided kwargs
-> 2397 fig.savefig(filename + t,
2398 dpi=dpi,
2399 bbox_inches=bbox_inches,
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/figure.py in savefig(self, fname, transparent, **kwargs)
2309 patch.set_edgecolor('none')
2310
-> 2311 self.canvas.print_figure(fname, **kwargs)
2312
2313 if transparent:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2191 else suppress())
2192 with ctx:
-> 2193 self.figure.draw(renderer)
2194
2195 bbox_inches = self.figure.get_tightbbox(
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/figure.py in draw(self, renderer)
1861
1862 self.patch.draw(renderer)
-> 1863 mimage._draw_list_compositing_images(
1864 renderer, self, artists, self.suppressComposite)
1865
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/projections/polar.py in draw(self, renderer, *args, **kwargs)
993 self.yaxis.set_clip_path(self.patch)
994
--> 995 Axes.draw(self, renderer, *args, **kwargs)
996
997 def _gen_axes_patch(self):
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/axes/_base.py in draw(self, renderer, inframe)
2746 renderer.stop_rasterizing()
2747
-> 2748 mimage._draw_list_compositing_images(renderer, self, artists)
2749
2750 renderer.close_group('axes')
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/axis.py in draw(self, renderer, *args, **kwargs)
1167
1168 for tick in ticks_to_draw:
-> 1169 tick.draw(renderer)
1170
1171 # scale up the axis label box to also find the neighbors, not
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/axis.py in draw(self, renderer)
289 for artist in [self.gridline, self.tick1line, self.tick2line,
290 self.label1, self.label2]:
--> 291 artist.draw(renderer)
292 renderer.close_group(self.__name__)
293 self.stale = False
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/text.py in draw(self, renderer)
695
696 gc = renderer.new_gc()
--> 697 gc.set_foreground(textobj.get_color())
698 gc.set_alpha(textobj.get_alpha())
699 gc.set_url(textobj._url)
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/backend_bases.py in set_foreground(self, fg, isRGBA)
953 self._rgb = fg
954 else:
--> 955 self._rgb = colors.to_rgba(fg)
956
957 def set_joinstyle(self, js):
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
187 rgba = None
188 if rgba is None: # Suppress exception chaining of cache lookup failure.
--> 189 rgba = _to_rgba_no_colorcycle(c, alpha)
190 try:
191 _colors_full_map.cache[c, alpha] = rgba
/home/linuxbrew/.linuxbrew/lib/python3.8/site-packages/matplotlib/colors.py in _to_rgba_no_colorcycle(c, alpha)
261 # tuple color.
262 if not np.iterable(c):
--> 263 raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
264 if len(c) not in [3, 4]:
265 raise ValueError("RGBA sequence should have length 3 or 4")
ValueError: Invalid RGBA argument: None
正如@JohanC 指出的那样,将 None
传递给 set_yticklabels
的 color
-kwarg 导致了 违反直觉的错误消息 我的问题。
避免 None
成功了,现在有效了。
为了安全起见,我编写了一个函数,避免将 None
传递给所涉及的任何 key-value 个参数(“kwargs”),可以在下面找到。
这是为了自动化一切,避免在每个需要彩色标签的绘图函数中编码过多。 该功能包括标记坐标轴、标题和颜色条的情况。
def set_ticklabels_or_title_of_current_ax(ax_or_cbar=None,
labels=None,
label_type=None,
ax_title_pos=(0.5, 0.985),
label_color=None,
font_weight=None,
special_textfont_size=None):
"""Function docs:\n
Avoid too much code in the main plotting function.
# NOTE on scope: not all of them are accepted as None since they could override the initial value
# Docs: https://whosebug.com/questions/63245556/valueerror-invalid-rgba-argument-none-when-plotting-via-matplotlib-ax-bar?noredirect=1#comment111839077_63245556
"""
# Check tick type passed
if label_type is None:
raise Exception("The user must pass a tick type (x or y).")
# Check whether an axis has been passed by the user
if ax_or_cbar is None and label_type.lower() in [
"x", "x-axis", "y", "y-axis", "title"
]:
ax_or_cbar = plt.gca()
# In the case that all variables were passed as None, return the axis unchanged
# NOTE: the function used here "check_if_any_or_all_of_the_passed_vars_are_None()" is a custom function, not included here: can be ignored
if tools.check_if_any_or_all_of_the_passed_vars_are_None(
[label_color, font_weight, special_textfont_size],
raise_error_within_function=False,
any_is_None=False):
# Return the ax unchanged
return ax_or_cbar
# * Check if labels were passed * #
if labels is None:
if label_type.lower() in ["x", "x-axis"]:
labels = [elem.get_text() for elem in list(ax_or_cbar.get_xticklabels())]
elif label_type.lower() in ["y", "y-axis"]:
labels = [elem.get_text() for elem in list(ax_or_cbar.get_yticklabels())]
elif label_type.lower() in ["title", "cbar title"]:
raise Exception("No title label has been passed.")
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
labels = list(ax_or_cbar.ax.get_yticklabels())
# * Check which variables were passed as None * #
if label_color is not None and font_weight is not None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
color=label_color,
weight=font_weight,
fontsize=special_textfont_size)
elif label_color is not None and font_weight is not None and special_textfont_size is None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
color=label_color,
weight=font_weight)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
color=label_color,
weight=font_weight)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color,
weight=font_weight)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, color=label_color, weight=font_weight)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
color=label_color,
weight=font_weight)
elif label_color is not None and font_weight is None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
color=label_color,
fontsize=special_textfont_size)
elif label_color is None and font_weight is not None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
weight=font_weight,
fontsize=special_textfont_size)
elif label_color is None and font_weight is None and special_textfont_size is not None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels, fontsize=special_textfont_size)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels, fontsize=special_textfont_size)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
fontsize=special_textfont_size)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, fontsize=special_textfont_size)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels,
fontsize=special_textfont_size)
elif label_color is None and font_weight is not None and special_textfont_size is None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels, weight=font_weight)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels, weight=font_weight)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
weight=font_weight)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, weight=font_weight)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels, weight=font_weight)
elif label_color is not None and font_weight is None and special_textfont_size is None:
if label_type.lower() in ["x", "x-axis"]:
ax_or_cbar.set_xticklabels(labels, color=label_color)
elif label_type.lower() in ["y", "y-axis"]:
ax_or_cbar.set_yticklabels(labels, color=label_color)
elif label_type.lower() == "title":
ax_or_cbar.set_title(labels,
position=ax_title_pos,
color=label_color)
elif label_type.lower() == "cbar title":
ax_or_cbar.set_label(labels, color=label_color)
elif label_type.lower() in [
"cbar yticklabels", "cbar yticks", "cbar y"
]:
ax_or_cbar.ax.set_yticklabels(labels, color=label_color)
# Return updated axis to user
return ax_or_cbar