Format Altair choropleth map legend scale and tooltip - tooltip

I am trying to make the tool tip 'Percentage' be an actual percent and not a decimal. Even when I include alt.Tooltip('Percentage:Q',format='.2%'), it doesn't seem to work.
Also, I am trying to make the legend scale from 0-100% instead of 40-70%.
Any help would be appreciated!
import altair as alt
from vega_datasets import data
states = alt.topo_feature(data.us_10m.url, 'states')
variable_list = ['Percentage', 'State Name', 'state_id']
alt.Chart(states).mark_geoshape().encode(
color=alt.Color('Percentage:Q', title='Positive NFB', legend=alt.Legend(format=".0%"), scale=alt.Scale(scheme='yellowgreen')),
tooltip=['State Name:N', 'Percentage:Q', alt.Tooltip('Percentage:Q',format='.2%')]).properties(title="Percentage of People in Households with Positive NFB"
).transform_lookup(
lookup='id',
from_=alt.LookupData(states_positive_NFB, 'state_id', variable_list)
).properties(
width=500,
height=300
).project(
type='albersUsa'
)
Current map:

To change the domain of the color scale, you can pass the domain argument to alt.Scale(): e.g.
alt.Scale(scheme='yellowgreen', domain=[0, 1])
To make the tooltip format appear, you can remove the duplicated tooltip encoding, as the first one appears to be taking precedence. That is, rather than
tooltip=['State Name:N', 'Percentage:Q', alt.Tooltip('Percentage:Q',format='.2%')]
you should use
tooltip=['State Name:N', alt.Tooltip('Percentage:Q', format='.2%')]

Related

"For all" using Apache Jenas rule engine

I'm currently working on some small examples about Apache Jena. What I want to show is universal quantification.
Let's say I have balls that each have a different color. These balls are stored within boxes. I now want to determine whether these boxes only contain balls that have the same color of if they are mixed.
So basically something along these lines:
SAME_COLOR = ∃x∀y:{y in Box a → color of y = x}
I know that this is probably not possible with Jena, and can be converted to the following:
SAME_COLOR = ∃x¬∃y:{y in Box a → color of y != x}
With "not exists" Jena's "NoValue" can be used, however, this does (at least for me) not work and I don't know how to translate above logical representations in Jena. Any thoughts on this?
See the code below, which is the only way I could think of:
(?box, ex:isA, ex:Box)
(?ball, ex:isIn, ?box)
(?ball, ex:hasColor, ?color)
(?ball2, ex:isIn, ?box)
(?ball2, ex:hasColor, ?color2)
NotEqual(?color, ?color2)
->
(?box, ex:hasSomeColors, "No").
(?box, ex:isA, ex:Box)
NoValue(?box, ex:hasSomeColors)
->
(?box, ex:hasSomeColors, "Yes").
A box with mixed content now has both values "Yes" and "No".
I've ran into the same sort of problem, which is more simplified.
The question is how to get a collection of objects or count no. of objects in rule engine.
Given that res:subj ont:has res:obj_xxx(several objects), how to get this value in rule engine?
But I just found a Primitive called Remove(), which may inspire me a bit.

How to get the bounding box from a Revit Element with Revit API, then call to center of that bounding box

I am trying to rotate Revit elements about their center points. In order to do that, I need to select a Revit element and find its center point, then create a line with the coordinates at that elements center point.
My best idea to accomplish this is to wrap a Revit element in a bounding box and then find the center of that box. My problem is that I am unsure how to accomplish this.
I am using pyRevit (amazing tool) and I am stuck on how to either wrap the selected element with a bounding box or retrieve its existing bounding box.
Any help would be greatly appreciated! I am really trying to learn the Revit API and understand how everything works. I am making progress but there is a lot to unpack.
def pickobject():
from Autodesk.Revit.UI.Selection import ObjectType
#define the active Revit application and document
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
#define a transaction variable and describe the transaction
t = Transaction(doc, 'This is my new transaction')
# Begin new transaction
t.Start()
# Select an element in Revit
picked = uidoc.Selection.PickObject(ObjectType.Element, "Select something.")
### ?????????? ###
# Get bounding box of selected element.
picked_bb = BoundingBoxXYZ(picked)
# Get max and min points of bounding box.
picked_bb_max = picked_bb.Max
picked_bb_min = picked_bb.Min
# Get center point between max and min points of bounding box.
picked_bb_center = (picked_bb_max + picked_bb_min) / 2
### ?????????? ###
# Close the transaction
t.Commit()
return picked, picked_bb_center
Thanks in advance for taking a look at what I have so far. Please let me know if anything needs further clarification!
edit:
#CyrilWaechter
I think you are right. Using LocationPoint would probably make more sense. I looked through the script you linked (thank you btw!) and I tried implementing this section in my code.
transform = doc.GetElement(picked.ElementId).GetTransform()
I am passing the ElementId through this statement but I get the error, "Wall" object has no attribute 'GetTransform'. Could you please help me understand this?
edit 2:
Thanks #JeremyTammik and #CyrilWaechter, your insights helped me understand where I was going wrong. While I still feel that certain properties are ambiguous in the Revit API, I was able to get my code to execute properly. I will post the code that I was able to get working below.
The centre of the bounding box is very easy to obtain. picked is a Reference. Get the ElementId from that, open it using doc.GetElement, and retrieve the bounding box using get_BoundingBox, cf. Conduits Intersecting a Junction Box
:
Element e = Util.SelectSingleElement(
uidoc, "a junction box" );
BoundingBoxXYZ bb = e.get_BoundingBox( null );
For certain elements and certain irregular shapes, you might want to use the centroid instead of the bounding box:
Solid Centroid and Volume Calculation
GetCentroid on GitHub
Edited and preserved for posterity by The Building Coder:
Python Rotate Picked Around Bounding Box Centre
Many thanks to Christian for the interesting discussion and Cyril for the wealth of additional information he provides!
Here is how I was able to solve my problem using pyRevit. This code allows you to rotate an element about its Z axis from the center of its bounding box.
To use this code, select a single Revit element and then open the Revit Python Shell. Copy and paste the code below into the Revit Python Shell notepad and click the run button. This will rotate the element by 45 degrees because the current rotateSelectedElement() argument is 45. You may change this number to any value before running.
# Import the math module to convert user input degrees to radians.
import math
# Get a list of all user selected objects in the Revit Document.
selection = [doc.GetElement(x) for x in uidoc.Selection.GetElementIds()]
# Definitions
def rotateSelectedElement(degrees_to_rotate):
from Autodesk.Revit.UI.Selection import ObjectType
#define the active Revit application and document
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
#define a transaction variable and describe the transaction
t = Transaction(doc, 'This is my new transaction')
# Convert the user input from degrees to radians.
converted_value = float(degrees_to_rotate) * (math.pi / 180.0)
# Begin new transaction
t.Start()
# Get the first selected element from the current Revit doc.
el = selection[0].Id
# Get the element from the selected element reference
el_ID = doc.GetElement(el)
# Get the Bounding Box of the selected element.
el_bb = el_ID.get_BoundingBox(doc.ActiveView)
# Get the min and max values of the elements bounding box.
el_bb_max = el_bb.Max
el_bb_min = el_bb.Min
# Get the center of the selected elements bounding box.
el_bb_center = (el_bb_max + el_bb_min) / 2
#Create a line to use as a vector using the center location of the bounding box.
p1 = XYZ(el_bb_center[0], el_bb_center[1], 0)
p2 = XYZ(el_bb_center[0], el_bb_center[1], 1)
myLine = Line.CreateBound(p1, p2)
# Rotate the selected element.
ElementTransformUtils.RotateElement(doc, el, myLine, converted_value)
# Close the transaction
t.Commit()
# Execute
# Add the desired degrees to rotate by as an argument for rotateSelectedElement()
rotateSelectedElement(45)
edit: Made code clearer. Code now executes in Revit Python Shell without any further modifications. Refer to directions above if you have trouble!

Seaborn FacetGrid: while mapping a stripplot dodge not implemented

Using Seaborn, I'm trying to generate a factorplot with each subplot showing a stripplot. In the stripplot, I'd like to control a few aspects of the markers.
Here is the first method I tried:
import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time", hue="smoker")
g = g.map(sns.stripplot, 'day', "tip", edgecolor="black",
linewideth=1, dodge=True, jitter=True, size=10)
And produced the following output without dodge
While most of the keywords were implemented, the hue wasn't dodged.
I was successful with another approach:
kws = dict(s=10, linewidth=1, edgecolor="black")
tips = sns.load_dataset("tips")
sns.factorplot(x='day', y='tip', hue='smoker', col='time', data=tips,
kind='strip',jitter=True, dodge=True, **kws, legend=False)
This gives the correct output:
In this output, the hue is dodged.
My question is: why did g.map(sns.stripplot...) not dodge the hue?
The hue parameter would need to be mapped to the sns.stripplot function via the g.map, instead of being set as hue to the Facetgrid.
import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time")
g = g.map(sns.stripplot, 'day', "tip", "smoker", edgecolor="black",
linewidth=1, dodge=True, jitter=True, size=10)
This is because map calls sns.stripplot individually for each value in the time column, and, if hue is specified for the complete Facetgrid, for each hue value, such that dodge would loose its meaning on each individual call.
I can agree that this behaviour is not very intuitive unless you look at the source code of map itself.
Note that the above solution causes a Warning:
lib\site-packages\seaborn\categorical.py:1166: FutureWarning:elementwise comparison failed;
returning scalar instead, but in the future will perform elementwise comparison
hue_mask = self.plot_hues[i] == hue_level
I honestly don't know what this is telling us; but it seems not to corrupt the solution for now.

Remove legend bar in R using Image.Plot

This is the test code im using
x_coord <- c(1,2,3,4)
y_coord <- c(1,2,3,4)
value <- c(12,15,19,30)
foo <- data.frame(x_coord, y_coord, value)
library(MBA)
foo=foo[ order(foo[,1], foo[,2],foo[,3]), ]
mba.int <- mba.surf(foo, 300, 300, extend=T)$xyz.est
library(fields)
fields::image.plot(mba.int,legend.only = FALSE, axes=FALSE)
The axes part deletes the axis, but when i try to remove the legend bar, the vertical bar indicating the color measurements, it will not go away.
i have tried smallplot = 1, but that gives me an error but it gets rid of the vertical legend,
Anyone have any idea of how to get rid of the legend without any errors produced ?
If you don't want the color legend, just use the built-in image function instead. The function you are using is designed specifically for adding a legend easily.
If you want to keep the same color scheme as the fields image.plot function:
image(<your data>, ..., col = tim.colors())
Using this creates the exact same image without a legend.
The image and image.plot functions actually have quite different plotting functionality.
One problem (at least for me, trying to plot regional climate model data) with using the built-in image is that it cannot handle irregular grids. The image.plot function uses the poly.image function internally to create the plot. Both are included in the fields package. The good thing is that the poly.image function also can be used on its own, for example like this:
library("fields")
# create an example of an irregular 3x3 grid by adding random perturbations up to ±0.6
x <- matrix(rep(1:3,each=3) + 0.6*runif(9), ncol=3)
y <- matrix(rep(7:9,times=3) + 0.6*runif(9), ncol=3)
# 9 values, from 1 to 9
z <- matrix(1:9,nrow=3)
# Please avoid the default rainbow colours, see e.g.
# https://www.climate-lab-book.ac.uk/2014/end-of-the-rainbow/
# Other examples of colour schemes: https://colorbrewer2.org/
col <- colorRampPalette(c("#2c7bb6","#abd9e9","#ffffbf","#fdae61","#d7191c"))(9)
par(mfrow=c(1,3), mar=c(4,4,4,1), oma=c(0,0,0,0))
image(x=7:9,y=1:3,z,col=col, main="image()\n Only regular grid. Also note transposition.")
image.plot(x,y,z,col=col, main="image.plot()\n Always with colorbar.")
poly.image(x,y,z,col=col, main="poly.image()\n Does not include colorbar.")

How to select Highvalues of the candlestick with data source

I always see the code as datasource="series0".
If series(0) is a candlestick and I want to use Highvalues or Closevalues of the candlestick, how so I select that data? Something like datasource="series0.Highvalues"? (It's worth noting that I use teechart2011 Eval and VB6).
If series(1) is the financial function ExpMovAvg, how to define the width of the ExpMovAvg line with code?
Similarly how do I use the Closevalues in Series(0) for this function? Not merely datasource="series0". Thanks !
I always see the code as datasource="series0", if series(0) is a candlestick and I want to use Highvalues or Closevalues of the candlestick,how to select that data? datasource="series0.Highvalues"? (I use teechart2011 Eval and VB6)
Here you have a simple example in VB6. You can assign any of the 4 ValueLists in the Candle series (Open, Close, High, Low) to the be used by the function with the MandatoryValueList.ValueSource property:
TChart1.AddSeries scCandle
TChart1.Series(0).FillSampleValues
TChart1.AddSeries scLine
TChart1.Series(1).SetFunction tfExpMovAvg
TChart1.Series(1).DataSource = TChart1.Series(0)
TChart1.Series(1).MandatoryValueList.ValueSource = "Close" '"Open" "High" "Low"
if series(1) is the financial function ExpMovAvg, how to define the
width of the ExpMovAvg line with code?
You can set the series' Pen.Width property as follows:
TChart1.Series(1).Pen.Width = 2
Similarly how to use the Closevalues in Series(0) for this function?
not merely datasource="series0", thanks !
This is the same above, isn't it?

Resources