Text objects allow you to insert text anywhere on a plot.
To download this Jupyter Notebook, right click on the link and choose "Download Linked File As..." or "Save Link as...". Remember where you saved the downloaded file, which should have an .ipynb extension. (You'll need to launch the Jupyter notebook or JupyterLab instance from the location where you store the notebook file.)
For this particular notebook, you will also need to download the sample font file, "FFF_Tusj.ttf", from the GitHub repository for this notebook: https://github.com/CDAT/Jupyter-notebooks/tree/master/vcs/VCS_Text_Objects. Save the font file in the same location as this notebook.
One additional file, "clt.nc" is needed for the notebook. Follow the instructions in the VCS Basics or VCS Principles notebooks to download the "clt.nc" sample data file. Alternatively, copy the following lines of code into a new cell early on in this notebook and run the cell which will download the files to a "sample data" directory within the conda environment you are using to run this notebook.
import vcs import cdms2 import os vcs.download_sample_data_files()
The first code block below does the following:
As the output of the last line of code shows, a VCS text object is composed of two VCS objects: a Text Table object and a Text Orientation object.
import vcs canvas=vcs.init(geometry=(800,600),bg=True) txt = vcs.createtext() txt.list()
---------- Text combined (Tc) member (attribute) listings ---------- secondary method = Tc ---------- Text Table (Tt) member (attribute) listings ---------- Tt_name = __texttable_59297961364487 font = 1 spacing = 2 expansion = 100 color = [0.0, 0.0, 0.0, 100.0] fillincolor = 0 priority = 1 string = [''] viewport = [0.0, 1.0, 0.0, 1.0] worldcoordinate = [0.0, 1.0, 0.0, 1.0] x = None y = None projection = default ---------- Text Orientation (To) member (attribute) listings ---------- To_name = __textorientation_3585916609795 height = 14 angle = 0 path = right halign = left valign = half
The Text Table is mainly used to control the following:
The Text Orientation is mainly used to control the following:
The following section shows how to control the different attributes of the Text Orientation object.
To get started, though, it is useful to understand the basics of the
.y positioning attributes from the Text Table, since they are used extensively throughout this notebook.
To plot the text string "Hello VCS User" in the center of the plot area, first assign the string to the
.string attribute of the
txt text object, then use the x and y attributes.
By default, the lower-left corner of the viewport (the area available for plotting) has an (x, y) coordinate of (0, 0) and (1, 1) for the upper-right corner. Therefore use .5 for the x and y coordinates to plot the text in the center.
txt.string = 'Hello VCS User' txt.x = .5 txt.y = .5 canvas.plot(txt)
canvas.clear() txt = vcs.createtext() txt.string = "Example of BIG Text" txt.x = .5 txt.y = .5 txt.height = 30 canvas.plot(txt)
canvas.clear() txt.angle = 45 txt.height =20. txt.string = "Rotated Text" canvas.plot(txt)
canvas.clear() txt.angle = 0 txt.height =20. txt.string = "Non-rotated Text" canvas.plot(txt)
canvas.clear() line = vcs.createline() line.x = [.5,.5] line.y = [0.,1.] line.type ="dot" line.color=["grey"] center = vcs.createtext() center.x = .5 center.y = .5 center.string = "Centered Text" center.halign = "center" right = vcs.createtext() right.x = .5 right.y = .25 right.string = "Right Aligned Text" right.halign = "right" left = vcs.createtext() left.x = .5 left.y = .75 left.string = "Left Aligned Text" left.halign = "left" canvas.plot(center) canvas.plot(right) canvas.plot(left) canvas.plot(line)
canvas.clear() line = vcs.createline() line.y = [.5,.5] line.x = [0.,1.] line.type ="dot" line.color=["grey"] half = vcs.createtext() half.height = 20 half.halign = "center" half.x = .5 half.y = .5 half.string = "Half Aligned Text" half.valign = "Half" bottom = vcs.createtext() bottom.halign='center' bottom.height=20 bottom.x = .25 bottom.y = .5 bottom.string = "Bottom Aligned Text" bottom.valign = "bottom" top = vcs.createtext() top.halign='center' top.height=20 top.x = .75 top.y = .5 top.string = "Top Aligned Text" top.valign = "top" cap = vcs.createtext() cap.x = .75 cap.y = .75 cap.string = "Cap Aligned Text" cap.valign = "cap" canvas.plot(half) canvas.plot(bottom) canvas.plot(top) #canvas.plot(cap) canvas.plot(line)
['Adelon', 'Arabic', 'AvantGarde', 'Chinese', 'Clarendon', 'Courier', 'DejaVuSans', 'DejaVuSans-Bold', 'DejaVuSans-BoldOblique', 'DejaVuSans-ExtraLight', 'DejaVuSans-Oblique', 'DejaVuSansCondensed', 'DejaVuSansCondensed-Bold', 'DejaVuSansCondensed-BoldOblique', 'DejaVuSansCondensed-Oblique', 'Greek', 'Hebrew', 'Helvetica', 'Maths1', 'Maths2', 'Maths3', 'Maths4', 'Russian', 'Times', 'default']
In addition to names, fonts can be identified by their number. The first line of code below shows how to get the number of the "Times" font. The second line of code illustrates how to return the name of a font, given its number, "5" in this case.
print("The 'Times' font number is:",vcs.getfontnumber("Times")) print("The name of number 5 is:", vcs.getfont(5))
The 'Times' font number is: 6 The name of number 5 is: Adelon
canvas.clear() t = vcs.createtext() t.string = "Default as default font" t.x = .3 t.halign = "center" t.y = .5 canvas.plot(t) vcs.setdefaultfont("DejaVuSans-Bold") t = vcs.createtext() t.string = "DejaVuSans-Bold as default font" t.x = .7 t.halign = "center" t.y = .5 canvas.plot(t)
Now let's reset the default font to AvantGarde from DejaVuSans-Bold and display all the different fonts in a grid. Since the font names will overlap each other when displayed, let's use an angle of 30.
# reset default font to AvantGarde from DejaVuSans-Bold vcs.setdefaultfont("AvantGarde") txt.angle = 30 fonts = vcs.listelements("font") N = len(fonts) grid = 5. # 5x5 grid delta = 1./6. canvas.clear() for i, font in enumerate(fonts): print("I,f:",i,font) txt.font = font txt.string = font yindx = i % grid xindx = int(i/grid) txt.x = delta + xindx*delta txt.y = delta + yindx*delta dsp = canvas.plot(txt) dsp
I,f: 0 Adelon I,f: 1 Arabic I,f: 2 AvantGarde I,f: 3 Chinese I,f: 4 Clarendon I,f: 5 Courier I,f: 6 DejaVuSans I,f: 7 DejaVuSans-Bold I,f: 8 DejaVuSans-BoldOblique I,f: 9 DejaVuSans-ExtraLight I,f: 10 DejaVuSans-Oblique I,f: 11 DejaVuSansCondensed I,f: 12 DejaVuSansCondensed-Bold I,f: 13 DejaVuSansCondensed-BoldOblique I,f: 14 DejaVuSansCondensed-Oblique I,f: 15 Greek I,f: 16 Hebrew I,f: 17 Helvetica I,f: 18 Maths1 I,f: 19 Maths2 I,f: 20 Maths3 I,f: 21 Maths4 I,f: 22 Russian I,f: 23 Times I,f: 24 default
To be ready for the next example, let's reset the canvas, text string, angle, font size (height), and plotting location.
canvas.clear() txt.string = "A VCS Text Object" txt.angle = 0 txt.height = 12 txt.x = [.5] txt.y = [.5] canvas.plot(txt)
You can add TrueType fonts to VCS by using the
For the next lines of code to work properly, you need to download the sample font file, "FFF_Tusj.ttf", from the GitHub repo for this notebook: https://github.com/CDAT/Jupyter-notebooks/tree/master/vcs/VCS_Text_Objects. If you have not already done so, save the font file in the same location as this notebook.
canvas.clear() vcs.addfont("FFF_Tusj.ttf", name="Myfont") txt.font = "Myfont" canvas.plot(txt)
You can control the font
color via the color attribute. You can use a string representing the color name (e.g. "Red") or an index (e.g. 5) to set the color.
You can change the colormap via the
Here we'll build a plot with the text string "A VCS Text Object" displayed in three different colors at three different horizontal (x) locations in the center of the plot.
First let's plot a red version in the center of the plot. Since the last time we assigned a value to
txt.x it was 0.5 (
txt.x = [.5]), we do not need to change that value here.
canvas.clear() txt.font = "default" txt.color = "Red" canvas.plot(txt)
Next we'll add the text string in color 5 from the default colormap (a purplish color), a bit to the right of the red string.
txt.x += .2 txt.color = 5 canvas.plot(txt)
Finally, we'll add a yellow version to the left of the red by changing the colormap from the default to "AMIP" which has a yellow color as index 5 as opposed to a purple color. The change in color is solely due to the change in the colormap.
txt.colormap = "AMIP" # Changing the colormap which will change the color of index 5 txt.x -= .4 canvas.plot(txt)
The world coordinate attribute determines the coordinate values at the corners of the plot area or viewport. By default the viewport covers the whole canvas.
As mentioned above, within the viewport, the default lower-left corner has an (x, y) coordinate of (0, 0) and the upper-right corner (1, 1).
Sometimes we do not want the coordinate system to cover the whole page, but rather an area where data is plotted.
As an example, to move the viewport to display in the lower, right section of the canvas use the following code:
txt.viewport=[0.5,1,0,.5] # list the x bounds first, then y bounds fa = vcs.createfillarea() fa.x = [0.5, 1, 1, .5] fa.y = [0, 0, .5, .5] fa.color=[(80,80,80)] fa.style="hatch" fa.index=12 canvas.clear() canvas.plot(fa) txt.color="Red" txt.height=15 canvas.plot(txt) # we do not need to tweak our text object coordinates at all
Sometimes we would like to position the text based on actual, real-world coordinates rather than on a percentage of the page (e.g. .5 or 50%). In order to do this, we need to let VCS know about the world coordinates of its viewing area or viewport.
For context, let's plot a map of the Total Cloudiness,
clt, over the contiguous United States from the "clt.nc" NetCDF file that is part of the VSC sample data set. Once we've plotted the data, we'll add a text object.
First we open the data file and read its contents into the
f (for file) variable.
Next we define the latitude and longitude coordinates of our area of interest, the contiguous U.S.
We subset the total cloudiness data, create a template to use for plotting, and create an isofill of the data.
Next we define the bounds of the viewport and world coordinates.
Finally, we plot the subsetted data using the template. By specifying continents=3, the boundaries between Canada and Mexico are drawn as well as the U.S. state lines.
canvas.clear() import cdms2, os f=cdms2.open(os.path.join(vcs.sample_data,"clt.nc")) lon1 = -130. lon2 = -70. lat1= 25. lat2 = 50 subset = f("clt",latitude=(lat1,lat2), longitude=(lon1, lon2)) tmpl = vcs.createtemplate() iso = vcs.createisofill() iso.datawc_x1 = lon1 iso.datawc_x2 = lon2 iso.datawc_y1 = lat1 iso.datawc_y2 = lat2 txt.viewport = [tmpl.data.x1, tmpl.data.x2, tmpl.data.y1, tmpl.data.y2] txt.worldcoordinate = [lon1, lon2, lat1, lat2] canvas.plot(subset,tmpl,iso, continents=3)
Next we'll plot the location of Washington D.C. which is at -77.0369 latitude and 38.9072 longitude.
txt.font = "default" txt.color = "Red" txt.height = 20 txt.halign = "center" txt.valign = "half" txt.x = -77.0369 txt.y = 38.9072 txt.string = "Washington D.C." canvas.plot(txt)
If your world coordinates represent latitude and longitude, you can use the
projection attribute to apply a projection (and its settings) to your text location.
The following example again uses the Total Cloudiness sample data file, "clt.nc".
The final image includes two plots, the top of which plots the data on a rectangle covering the globe from -180 to 180 degrees longitude and -90 to 90 degrees latitude. The bottom, or second, plot uses a Polar projection.
The first use of the text object for plotting "Non proj" in blue on the top plot, does not use a projection, but does use the world coordinate. The second use of the text object to plot "PROJECTED" in red, does use the Polar projection.
canvas.clear() bot = canvas.gettemplate("bot_of2") top = canvas.gettemplate("top_of2") gm = canvas.createisofill() gm.datawc_x1 = -180 gm.datawc_x2 = 180 gm.datawc_y1 = -90 gm.datawc_y2 = 90 canvas.plot(f("clt", slice(0,1)),gm,top) proj = "polar" gm.projection = proj canvas.plot(f("clt",slice(0,1),longitude=(-180,181)),gm,bot) txt = vcs.createtext() txt.string = "Non proj" txt.worldcoordinate = [-180,180,-90,90] txt.x = -30 txt.y = 80 txt.color="blue" txt.height = 15 txt.halign = "center" txt.viewport = top.data.x1, top.data.x2, top.data.y1, top.data.y2 canvas.plot(txt) txt.projection = proj txt.color = "red" txt.string = "PROJECTED" txt.viewport = bot.data.x1, bot.data.x2, bot.data.y1, bot.data.y2 canvas.plot(txt)
txt.priority = 0 # Turn off txt.priority = 2 # Move to a layer on top of the "default" layer (1)
The following attributes are left over from XGKS and are not used anymore:
canvas.clear() # Continental U.S.A. region lat1 = 15. lat2 = 70. lon1 = -140. lon2 = -60. proj = "lambert" # Read this subset of data in clt = f("clt",time=slice(0,1),latitude=(lat1,lat2),longitude=(lon1,lon2),squeeze=1) # Use the Isofill method to plot the total cloudiness data gm = vcs.createisofill() gm.datawc_x1 = lon1 gm.datawc_x2 = lon2 gm.datawc_y1 = lat1 gm.datawc_y2 = lat2 gm.projection = proj # Use the default template, but don't modify it templ = vcs.createtemplate() # Create and define the text object txt = vcs.createtext() txt.string = ["Washington D.C.", "New York", "Los Angeles"] txt.halign = "center" txt.valign = "half" txt.color = "red" txt.font = "Myfont" txt.height = 15 txt.priority = 2 txt.angle = -5 txt.y = [38.9072, 40.7128, 34.0522] txt.x = [-77.0369, -74.0060, -118.2437] txt.worldcoordinate = [lon1, lon2, lat1, lat2] txt.viewport = [templ.data.x1, templ.data.x2, templ.data.y1, templ.data.y2] txt.projection = proj canvas.plot(clt,gm) canvas.plot(txt)
The CDAT software was developed by LLNL. This work was performed under the auspices of the U.S. Department of Energy by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
If you have questions about this notebook, please email our CDAT Support address, firstname.lastname@example.org.