如何根据数字符号更改matplotlib中的标记 [英] How to change marker in matplotlib based on sign of number
问题描述
概述
我有一些类似的数据:
- X值:频率范围
- Y值:
float
可以为正或负的值- 如果您好奇,则Y值为电抗
- X values: range of frequencies
- Y values:
float
value that can be positive or negative- The Y-value is electrical reactance, if you're curious
我用对数-对数图表示数据.由于您只能取正数的对数,因此我绘制
abs(Y-value)
.I represent the data in a log-log plot. Since you can only take the logarithm of a positive number, I plot
abs(Y-value)
.在对数-对数图上,我想通过更改标记符号来表示原始数字的符号:
On the log-log plot, I would like to represent the original number's sign by changing the marker symbol:
-
+
标记(如果符号为+
)
-
-
标记(如果符号为-
)
+
marker if sign was+
-
marker if sign was-
通常:下面,我放置了当前的方法.我想做得更好".希望
matplotlib
有更标准的方法来实现这一点.Generally: below I have placed my current method. I would like to "do it better". Hopefully
matplotlib
has a more standard way of doing this.详细信息
目前,这是我的情节:
这是我当前代码的相似之处(请注意:数据是从设备中提取的,因此在这种情况下,我只使用了
random.uniform
):Here is some semblance of my current code (note: the data was pulled from equipment, so I just used
random.uniform
in this case):import numpy as np import matplotlib.pyplot as plt from random import uniform # Generating data num_pts = 150 freq_arr = np.logspace(start=2, stop=6, num=num_pts, base=10) reactance_arr = [uniform(-1000,1000) for i in range(num_pts)] abs_reactance_arr = [abs(i) for i in reactance_arr] reactance_signed_marker = [1 if reactance_arr[i] >= 0 else -1 for i in range(len(reactance_arr))] # Taken from here: https://stackoverflow.com/questions/28706115/how-to-use-different-marker-for-different-point-in-scatter-plot-pylab x = np.array(freq_arr) y = np.array(abs_reactance_arr) grouping = np.array(reactance_signed_marker) # Plotting fig1, ax1 = plt.subplots() positives_line = ax1.scatter( x[grouping == 1], y[grouping == 1], s=16, marker="+", label="Reactance", ) # Match color between the two plots col = positives_line.get_facecolors()[0].tolist() ax1.scatter( x[grouping == -1], y[grouping == -1], s=16, marker="_", label="Reactance", color=col, ) ax1.set_xlim([freq_arr[0], freq_arr[-1]]) ax1.set_xscale("log") ax1.set_xlabel("Frequency (Hz)") ax1.set_yscale("log") ax1.set_ylabel("Value (Ohm)") ax1.legend() ax1.set_title("Reactance")
我该如何做得更好?目前,这感觉非常手动.我想知道:
How can I do this better? Currently, this feels very manual. I am wondering:
- 是否有更好的方法将
-
和+
值解析为标记?- 当前方法非常麻烦:1.绘制
+
,2.提取颜色,3.绘制具有相同颜色的-
- Is there a better way to parse
-
and+
values into markers?- The current way is quite cumbersome with 1. plotting
+
, 2. extracting color, 3. plotting-
with the same color
推荐答案
I proposed a scatter with multiple markers in iterating markers in plots. Applying it here would look like:
import numpy as np import matplotlib.pyplot as plt def mscatter(x, y, ax=None, m=None, **kw): import matplotlib.markers as mmarkers if not ax: ax=plt.gca() sc = ax.scatter(x,y,**kw) if (m is not None) and (len(m)==len(x)): paths = [] for marker in m: if isinstance(marker, mmarkers.MarkerStyle): marker_obj = marker else: marker_obj = mmarkers.MarkerStyle(marker) path = marker_obj.get_path().transformed( marker_obj.get_transform()) paths.append(path) sc.set_paths(paths) return sc # Generating data num_pts = 150 freq_arr = np.logspace(start=2, stop=6, num=num_pts, base=10) reactance_arr = np.random.uniform(-1000,1000,num_pts) x = np.array(freq_arr) y = np.abs(reactance_arr) markers = np.array(["_", "+"])[(reactance_arr >= 0).astype(int)] # Plotting fig1, ax1 = plt.subplots() mscatter(x, y, ax=ax1, s=16, m = markers, label="Reactance") ax1.set_xlim([freq_arr[0], freq_arr[-1]]) ax1.set_xscale("log") ax1.set_xlabel("Frequency (Hz)") ax1.set_yscale("log") ax1.set_ylabel("Value (Ohm)") ax1.legend() ax1.set_title("Reactance") plt.show()
这篇关于如何根据数字符号更改matplotlib中的标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- The current way is quite cumbersome with 1. plotting
- 当前方法非常麻烦:1.绘制