gpt4 book ai didi

python - 使用 matplotlib 为 svg 线图创建工具提示

转载 作者:行者123 更新时间:2023-12-05 08:12:08 27 4
gpt4 key购买 nike

我想为使用 matplotlib 创建的 SVG 折线图创建工具提示(显示数据值)。这将使用户能够单击或将鼠标悬停在显示该特定点值的折线图中的每个标记上。

为了能够做到这一点,我需要访问 Line2D 对象的标记元素并为每个此类元素添加一个 gid。

http://matplotlib.org/examples/user_interfaces/svg_histogram.html ,有一个关于如何对直方图完成此操作的示例。

H = plt.hist([r,r1], label=labels)
containers = H[-1]
hist_patches = {}
for ic, c in enumerate(containers):
hist_patches['hist_%d'%ic] = []
for il, element in enumerate(c):
element.set_gid('hist_%d_patch_%d'%(ic, il))
hist_patches['hist_%d'%ic].append('hist_%d_patch_%d'%(ic,il))

但是,如果我尝试使用折线图执行此操作,我会发现 Line2D 对象不可迭代——可能是因为它不是像直方图条那样的补丁集合。

H = plt.plot([1,2,3,4],[1,4,9,16], 'ro')
containers = H[-1]
enumerate(containers)

这导致:“TypeError:‘Line2D’对象不可迭代”

问题是如何从 Line2D 访问单个标记

有一些方法可以使用 matplotlib 的交互式后端来做到这一点。但是我需要为非交互式 SVG 实现它。

最佳答案

我修改了 OPs linked code snippet 中的代码

这至少对我有用。但是,我还没有找到区分单个标记的方法

import matplotlib.pyplot as plt
import numpy as np
import xml.etree.ElementTree as ET
from io import BytesIO

plt.rcParams['svg.fonttype'] = 'none'
_ , ax = plt.subplots(figsize=(14,8))

Rand_Values = []
Rand_Values.append(np.random.rand(20))
Rand_Values.append(np.random.rand(20))
x_axis = range(20)

for i in range(2):
H = ax.plot(x_axis, Rand_Values[i] , label= "data set %i" % (i+1))
ThisContainer = H[-1]
ThisContainer.set_gid('hist_%i' % i )

plt.xlabel("x-axis label")
plt.ylabel("random data")
plt.title( "Interactive chart" )

leg = ax.legend(loc='upper left', bbox_to_anchor=(0, 1), ncol=1, fancybox=True, shadow=True)

for i, t in enumerate(leg.get_texts()):
t.set_gid('leg_text_%d' % i)

# Save SVG in a fake file object.
f = BytesIO()
plt.savefig(f, format="svg")

# Create XML tree from the SVG file.
ET.register_namespace("", "http://www.w3.org/2000/svg")
tree, xmlid = ET.XMLID(f.getvalue())

# --- Add interactivity ---
# Add attributes to the text objects.
for i, t in enumerate(leg.get_texts()):
el = xmlid['leg_text_%d' % i]
el.set('cursor', 'pointer')
el.set('onclick', "toggle_hist(this)")

# Create script defining the function `toggle_hist`.
script = """
<script type="text/ecmascript">
<![CDATA[

function toggle(oid, attribute, values) {
/* Toggle the style attribute of an object between two values.

Parameters
----------
oid : str
Object identifier.
attribute : str
Name of style attribute.
values : [on state, off state]
The two values that are switched between.
*/
var obj = document.getElementById(oid);
var a = obj.style[attribute];

a = (a == values[0] || a == "") ? values[1] : values[0];
obj.style[attribute] = a;
}

function toggle_hist(obj) {
var num = obj.id.replace( /^\D+/g, '');
toggle( 'leg_text_' + num, 'opacity', [1, 0.5]);
toggle( 'hist_'+ num , 'opacity', [1,0]);
}
]]>
</script>
"""

# Add a transition effect
css = tree.getchildren()[0][0]

css.text = css.text + "g {-webkit-transition:opacity 0.4s ease-out;" + \
"-moz-transition:opacity 0.4s ease-out;}"


# Insert the script and save to file.
tree.insert(0, ET.XML(script))

ET.ElementTree(tree).write("svg_lineChart.svg")

关于python - 使用 matplotlib 为 svg 线图创建工具提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30067642/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com