简体   繁体   中英

get matplotlib / cartopy contour auto label coordinates

How can I retrieve the automatically determined contour label coordinates in the example below?

matplotlib example from the documentation

import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt


delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2

fig, ax = plt.subplots()
CS = ax.contour(X, Y, Z)
CS_labels = ax.clabel(CS, inline=True, fontsize=10)
ax.set_title('Simplest default with labels')

在此处输入图像描述

I would like to do something like

label_locations = CS_labels.get_label_coords()

So that I can start with an auto-selected set and modify manually as needed. This would be especially helpful when dealing with labels in geospatial coordinates .

Update:
The solution provided by swatchai works for both matplotlib and cartopy.

for txobj in CS.labelTexts:
    pos = txobj.get_position()
    txt = txobj.get_text()
    print(pos, txt)

Label positions are best retrieved from the CS object, instead of the CS_labels object.

Note:
tdy's solution only works for matplotlib, but not when using cartopy GeoAxes, as ax.clabel() returns 'NoneType' for CS_labels so CS_labels[0].get_position() cannot be accessed that way.

If I understand correctly, you can use this:

label_locations = [label.get_position() for label in CS_labels]

# [( 0.9499999999999864,   0.5360418495133943),
#  ( 1.8999999999999821,   1.755885999331959),
#  ( 0.15000000000000968,  0.8499999999999899),
#  (-0.9000000000000075,  -0.75588599933193),
#  ( 0.4135112591682213,   0.124999999999992),
#  (-0.42169775490495853, -0.2750000000000066)]

For cartopy, once you created contour labels, you can get access to the labels by

CS.labelTexts  #CS is contour_collection set

Here is the runnable code that demonstrates all the steps.

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy
import numpy as np

delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 3.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)*20
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)*20
Z = (Z1 - Z2) * 2

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

CS = ax.contour(X, Y, Z)

ax.clabel(
    CS,
    colors=['black'],
    manual=False,
    inline=True,
    fmt=' {:.0f} '.format
)

ax.set_extent([-3,3,-2,3])
ax.gridlines(draw_labels=True)
plt.show()

等高线图

To list the contour label texts:-

CS.labelTexts

Output:

[Text(1.003030188944607, 0.7749999999999897, ' -30 '),
 Text(1.4249999999999843, 1.7059169688922102, ' -20 '),
 Text(0.30880609807150927, 0.9499999999999895, ' -10 '),
 Text(0.6000000000000081, 0.3999999999999915, ' 0 '),
 Text(-0.7000000000000091, -0.9440944811557408, ' 10 '),
 Text(-0.12500000000001066, -0.8102372655970758, ' 20 '),
 Text(-0.050000000000010925, 0.24709487906649752, ' 30 ')]

To print position and text of each label:-

for txobj in CS.labelTexts:
    pos = txobj.get_position()
    txt = txobj.get_text()
    print(pos, txt)

The output:

(1.003030188944607, 0.7749999999999897)  -30 
(1.4249999999999843, 1.7059169688922102)  -20 
(0.30880609807150927, 0.9499999999999895)  -10 
(0.6000000000000081, 0.3999999999999915)  0 
(-0.7000000000000091, -0.9440944811557408)  10 
(-0.12500000000001066, -0.8102372655970758)  20 
(-0.050000000000010925, 0.24709487906649752)  30 

If you want to manipulate each of the labels, the methods .set_text() and .set_position() are often used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM